Search code examples
c++node.jsrestpoco-libraries

Poco library PUT method not working as expected although host, method, content-type are set correctly


I have the following code in C++ with Poco Library that should perform a PUT on localhost with a body like {"name" : "sensorXXX", "totalLots" : 50, "occupied": 5}

string url = String("http://localhost:3000/cam1111");
URI uri(url);
HTTPClientSession session(uri.getHost(), uri.getPort());

// prepare path
string path(uri.getPathAndQuery());
if (path.empty()) path = "/";

// send request
HTTPRequest req(HTTPRequest::HTTP_PUT, path, HTTPMessage::HTTP_1_1);
req.setContentType("application/json");

string body = string("{\"name\" : \"Parking Sensor developed by aromanino\", \"totalLots\" : 50, \"occupied\": 5}");
// Set the request body
req.setContentLength( body.length() );

// sends request, returns open stream
std::ostream& os = session.sendRequest(req);
cout<<"request sent to " <<uri.getHost()<<endl;
cout<<"port "<<uri.getPort()<<endl;
cout<<"path "<<uri.getPathAndQuery()<<endl;
cout<<"body:\n"<<body<<endl;

HTTPResponse res;
cout << res.getStatus() << " " << res.getReason() << endl;

return 0;

It is supposed to PUT on a local middleware done in NodeExpress.

I get 200 as response so it should be ok.

However the middleware is receiving something (so the host and port are correct) but it is not executing the end point which I am expecting which is:

router.put("/:dev", function(req, res){
    //console.log(req.params.dev);
    /*Check if request contains total and occupied in the body: If not reject the request.*/
    var stat;
    var body_resp = {"status" : "", "message" : ""};;
    console.log(req.body);
    ....
});

and it is not captured also by router.all('*', ...).

The same host, body, content-type are working as expected on Postman.

What am I supposed to set more in the Poco library to perform a correct PUT request.


Solution

  • You are not actually sending the body with the HTTP request, as in:

    std::ostream& os = session.sendRequest(req);
    os << body;
    

    Furthermore, you must also receive the server response after sending the request with the body - simply declaring the HTTPResponse object is not sufficient.

    HTTPResponse res;
    std::istream& is = session.receiveResponse(res);
    

    So, the complete snippet should be:

    string url = string("http://localhost:3000/cam1111");
    URI uri(url);
    
    HTTPClientSession session(uri.getHost(), uri.getPort());
    
    string path(uri.getPathAndQuery());
    if (path.empty()) path = "/";
    
    HTTPRequest req(HTTPRequest::HTTP_PUT, path, HTTPMessage::HTTP_1_1);
    req.setContentType("application/json");
    
    string body = string("{\"name\" : \"Parking Sensor developed by aromanino\", \"totalLots\" : 50, \"occupied\": 5}");
    req.setContentLength(body.length());
    
    std::ostream& os = session.sendRequest(req);
    os << body;
    
    HTTPResponse res;
    std::istream& is = session.receiveResponse(res);
    cout << res.getStatus() << " " << res.getReason() << endl;