Try to send POST method to server using JSON. But, server also requires model, platform and platform version as headers to request. How can I add these headers to HTTPRequest. At Postman, I can add it in Headers tab. Eg. Model: Redmi 4 Platform: android. Feel free to edit to make it clear to others.
Below there is my code who HTTPRequest creates:
Poco::JSON::Object obj;
obj.set("login", "log123");
obj.set("password","pas123");
Poco::Net::HTTPClientSession session("http://hostAddress",
80); //giving host name and port number
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST,
"http://requestAddress","1.1"); //initializing request body
Poco::Net::HTTPResponse response;
std::stringstream ss;
obj.stringify(ss);
request.setContentType("application/json");
request.setContentLength(ss.str().length());
std::ostream& oStream = session.sendRequest(request);// sends request, returns open stream
obj.stringify(oStream);
std::istream& iStream = session.receiveResponse(response);
I tried to find some information at https://pocoproject.org/docs/Poco.Net.HTTPRequest.html. https://pocoproject.org/docs/Poco.Net.HTTPMessage.html. But without results.
There is one solution. It can help to others.
request.add("string:key","string:value") //In order to add headers to request.
Eg:
request.add("X-Make","Xiaomi");
request.add("X-Model","Redmi 4");
request.add("X-Platform","android");
request.add("X-Platform-Version","6.0.1");
It works for me.
Related
I've to use a C++ library for sending data to a REST-Webservice of our company.
I start with Boost and Beast and with the example given here under Code::Blocks in a Ubuntu 16.04 enviroment.
The documentation doesn't helped me in following problem:
My code is, more or less, equal to the example and I can compile and send a GET-request to my test webservice successfully.
But how can I set data inside the request (req) from this definition:
:
beast::http::request<beast::http::string_body> req;
req.method("GET");
req.target("/");
:
I tried to use some req.body.???, but code completition doesn't give me a hint about functionality (btw. don't work). I know that req.method must be changed to "POST" to send data.
Google doesn't show new example about this, only the above code is found as a example.
Someone with a hint to a code example or using about the Beast (roar). Or should I use websockets? Or only boost::asio like answered here?
Thanks in advance and excuse my bad english.
Small addition to Eliott Paris's answer:
Correct syntax for setting body is
req.body() = "name=foo";
You should add
req.prepare_payload();
after setting the body to set body size in HTTP headers.
To send data with your request you'll need to fill the body and specify the content type.
beast::http::request<beast::http::string_body> req;
req.method(beast::http::verb::post);
req.target("/");
If you want to send "key=value" as a "x-www-form-urlencoded" pair:
req.set(beast::http::field::content_type, "application/x-www-form-urlencoded");
req.body() = "name=foo";
Or raw data:
req.set(beast::http::field::content_type, "text/plain");
req.body() = "Some raw data";
I made a google search before to write here. I'm using a Linux c++ server to send notifications to Windows Phone 8.1 - silverlight. Currently, using Poco library, I developed a simple code able to send a MPNS toast.
The snippet is the following:
URI uri(url);
string path(uri.getPathAndQuery());
if (path.empty()) path = "/";
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest request(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1);
request.setContentType("text/xml");
request.add("X-WindowsPhone-Target", "toast");
request.add("X-NotificationClass", "2");
request.setMethod(HTTPRequest::HTTP_POST);
request.setContentLength(payload.length());
request.write(std::cout);
session.sendRequest(request)<<payload;
HTTPResponse response;
std::istream& rs = session.receiveResponse(response);
Now I need to update my Windows phone to the WinRT 8.1 (no Silverlight) and the notification system is WNS.
Unfortunately I haven't found enough docs to do this in a raw mode as for MPNS outside Windows. And most of examples are in C# using .NET.
Did someone meet this problem or find docs about how to realize it?
Thank you for any suggestion.
Chris
In my project,I have encountered a serious problem which program can't receive data and then crash.
these are my code :
HTTPClientSession s("x.x.x.x",8000);
HTTPRequest request(HTTPRequest::HTTP_POST);
std::ostream& send = s.sendRequest(request);
std::string body = "<a> xml </a>";
request.setContentLength( body.length() );
send << body <<std::flush;
HTTPResponse response;
std::istream& res = s.receiveResponse(response);
StreamCopier::copyStream(res, std::cout);
After I run it,when my program received data from server,it crashed and throw
Poco::Net::messageException
.Oh,my god!
I traced it into internal code of POCO , finding :
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
is my data sended property in VS2005.
At the same time ,Poco find the last letter of <!DOCTYPE is Ewhich is not a space ,so it throw the exception.
Do any one encouter the case? who can help me ?Thank you ,very much!!!!
I'm sending data almost the same way. There's just one difference in my code.
request.setContentType("text/xml; charset=utf-8");
According to the source code of the Poco library, exception 'Poco::Net::MessageException' is raised because of malformed response from http server.
I am trying to use cpp-netlib in a project of mine. I simply need to create a HTTP proxy into which I can plug in some functionality later. For now, I just need to listen to requests, send request to a new site, and forward the answer of the new request to the first request.
This is the code I have so far:
std::string ip = source(request);
http::client client;
std::ostringstream url;
url << "www.example.com/image.jpg";
http::client::request clientRequest(url.str());
http::client::response clientResponse = client.get(clientRequest);
response = server::response::stock_reply(server::response::ok);
response.headers = clientResponse.headers(); //This is not possible - not correct type or something
response.content = clientResponse.body();
Results in error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::multimap<_Kty,_Ty>' (or there is no acceptable conversion)
A request to the test image I am using yields 19.4kb data in the response. If I do the same request through the above code (without header copying) I get an answer with about 4kb data, which the browser tries to show as text (default header). It does seem like an image though, even in text.
Anyone out there that is familiar with cpp-netlib-0.8? is response.content = clientResponse.body(); the correct way? How can I add the correct headers?
It's altogether too much template weirdness in cpp-netlib for me to understand it right now!
Thanks...
Instead of using:
response.content = clientResponse.body();
the correct way is:
std::string body_content = body(clientResponse);
also, you are using response as variable, while your variable is actually clientResponse
For more examples read cpp-netlib v0.8 documentation
I'm facing a problem with curl as I am unable to issue a PUT request with inline XML data, I'm not sure how its done but I hade a couple of goes on it with different techniques. First I tried using the CURLOPT_UPLOAD as its the default CURL option for PUT and tried to append the xml data manually:
typedef map<string, string> headers_t;
std::string strCommand = <XMLCOMMAND>
PUTRequest(param1, param2, ...)
{
...
headers_t headers;
int nLen = strCommand.length();
stringstream issLen;
issLen << nLen;
issLen >> strln;
curl_easy_setopt(curl, CURLOPT_UPLOAD, true); // HTTP PUT
headers.append("Content-Length: "+ strln); //
headers.append(strCommand);
...
}
Then I tried the same method but using the CURLOPT_POSTFIELDS and CURLOPT_POSTFIELDSIZE instead of manually appending the command to the HTTP headers.... did not work.
Then I tried customizing the PUT request using the CURLOPT_CUSTOMREQUESToption and setting the parameter to PUT and also manually appending the command and using the POSTFIELDS method.
Sadly none worked and now I'm clueless as of what to try next.
When using CURLOPT_UPLOAD, you are appending the XML to the headers of the request rather then to the body where it belongs. You need to use CURLOPT_READDATA (with CURLOPT_READFUNCTION if your XML is not in a file) to provide the XML data when curl asks for it, and also use CURLOPT_INFILESIZE/CURLOPT_INFILESIZE_LARGE so curl can generate a proper 'Content-Length' header (don't append that header manually).
If you use CURLOPT_POST, then use CURLOPT_POSTFIELDS and CURL_POSTFIELDSIZE/CURLOPT_POSTFIELDSIZE_LARGE to provide the actual XML data, but then you also have to use CURLOPT_HTTPHEADER to override the default 'Content-Type' header so you can change it from the default value of 'application/x-www-form-urlencoded' to 'text/xml' instead.