CUrl PUT with xml data - c++

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.

Related

C++ Boost http post request [duplicate]

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";

chilkat CkHttp c++ : need Content-Length=0 using PUT and DELETE verbs

I'm using Chilkat 9.5.0.75 x86-vc10-sp1 ( and tested on 9.5.0.76 too ).
I need to use a webservice that requires Content-Length specified also for PUT and DELETE calls with empty body. I read this http://www.chilkatforum.com/questions/5485/need-content-length0-http-header-even-when-message-is-empty/5528 from the old forum, but I still have the issue.
Is there any workaround ?
This is the way I make the PUT call
CkHttp http;
if (!http.UnlockComponent(CK_UNLOCKCODE)) return false;
http.put_SessionLogFilename("http.txt");
http.AddQuickHeader("X-Authorization", authToken);
http.AddQuickHeader("Accept", "application/json");
CkString os;
http.QuickPutStr(endpoint, os);
int res = http.get_LastStatus();
Thank you for any advice
AddQuickHeader is deprecated, use SetRequestHeader instead.
If you explicitly set the Content-Length to 0, it should result in the "Content-Length: 0" header being added to the request.
http.SetRequestHeader("Content-Length","0");
Normally you would never explicitly set the Content-Length header because Chilkat automatically adds it (if non-zero) based on the actual content length.

Poco HTTPClientSession adding headers to HTTPRequest

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.

Returning JSON object to HTTP POST REST call from C++

I have a C++ API that is exposed to the web via REST. I have written the applications as FastCGI processes. I am able POST to the apps with data in the body and get back text. But now, instead of text, I want to return data as a JSON object.
I have the output packaged into a JSON file already. I just need to know how to pass this back to the requester.
Edit:
I currently have something like this: http://pastebin.com/vhC30kTJ
In this, I am printing text in the printcontent(string) function. The text I am printing using cout is passed back to the HTTP requester by FastCGI. I want to pass JSON instead, and I have no idea how to do that. I am able to write the data into a JSON file. Do I pass back a JSON file or do I pass back a json style string? I am confused.
Ideally, the function forming the JSON should accept a parameter of std::ostream &. Then, if you want to write to a file you pass in an std::ofstream and if you want to write it to standard output (which is what you want to do in this case, so that it gets sent to the browser) you can just pass in std::cout. Make sure you write out the required HTTP headers and the blank line first, or the server/browser will try to interpret the JSON as HTTP headers.
void makejson(ostream & output, string content)
{
/* output << "{\"some\":\"json\"}" */
}
// Write to file
ofstream file("data.json");
makejson(file, "somedata");
file.close();
// Write to browser
cout << "Content-Type: application/json\r\n\r\n";
makejson(cout, "somedata");

Node.js http.ClientRequest: get raw headers

I am using Node.js 0.2.3 and response.headers['set-cookie'] seems to be truncated after the first cookie. Is there any way I can just read the raw headers?
BTW, the set-cookie header should contain:
id1=sw34rwdsfsd;secure;
id2=wer235sd2354;secure;
id3=df435df4543;secure
My guess would be it is not parsing the boolean attributes right and stops after the first one. Anyone know if this is fixed in later versions of Node.js (even though I can't upgrade just yet)?
var spawn = require('child_process').spawn;
function getHeader(url, callback){
var client = spawn('curl', ['-I', url]);
client.stdout.setEncoding('***');
client.stdout.on('data', function(data){
callback(data);
});
}
The -I flag asks curl for just the header. Pass whatever encoding to setEncoding - I think it defaults to the raw that you're looking for.