Link to home
Start Free TrialLog in
Avatar of Eric Zwar
Eric ZwarFlag for Australia

asked on

C++ cpprestsdk POST question

Hi, I have a cpprestsdk test program which calls a PHP back-end on my localhost passing GET data and this works fine.  But I want to pass the data via POST rather than GET and though I have Googled intensely I cannot get any of the suggestions to work in my environment which is Win 10 and VS2019.
I've attached the GET code which works.
If you can advise me how to achieve the similar functionality but sending the data to the backend via POST I would be most appreciative and thank you in anticipation.User generated imageUser generated image
Avatar of Eric Zwar
Eric Zwar
Flag of Australia image

ASKER

I should add that the code that works was adapted from http://www.drdobbs.com/windows/using-the-microsoft-c-rest-sdk/240164544?pgno=2 with many thanks to that author.
Avatar of hielo
I have never used this SDK, but when it comes to doing POST requests, you typically should include the "Content-Length" and "Content-Type" headers.

The code you posted uses an instance of http_client to send the request, but I don't see a way to augment the headers.  However, if you look at the http_client class reference, you will notice that the first response() method listed accepts an instance of http_request.  So, try creating an instance of http_request an add the headers I mentioned above.  So, try:

pplx::task<void> HTTPPostAsync(){
	http_client client("http://localhost/path/to/file.php");

	http_request request(methods::POST);
	request.headers().add("Content-Type", "application/x-www-form-urlencoded");
	request.headers().add("Content-Length", "21");//length of the submitted data/payload (in bytes)
	// request.headers().add("Host", "ericzwar.com");
	request.headers().add("X-Requested-With", "Casablanca");
	request.set_body("user=john&password=hi");// 21 bytes long

	return client.request(request).then([](http_response response){
		// process response here
	});
}

Open in new window

Hi Hielo,  thank you for your response but I get two errors:

no instance of function template "web::http::http_headers::add" matches the argument list      
argument types are: (const char [13], const char [34])
object type is: web::http::http_headers

This error shows if I leave the () in.  (It is in lines 22 and 23 in my source but lines 5 and 6 in your example above)

If I leave the () out then I get:
"left of add must have a class/struct/union" (lines 5 and 6 in your example)  - lines 22 and 23 in my source.

I have Googled on these errors but can't seem to find exactly what is required.

Looking forward to your advice and thank you in anticipation.
Note: my environment is Windows 7 with Visual Studio 2015 Community if that helps.
I found a headers test page where the values are U("...") instead of just "...", so try:
	request.headers().add( U("Content-Type"), U("application/x-www-form-urlencoded") );
	request.headers().add( U("Content-Length"), U("21") );//length of the submitted data/payload (in bytes)

Open in new window

Also, I looked at the http_headers class reference and I see that it contains the following methods:
  • set_content_type(utility::string_t type)
  • set_content_length(utility::size64_t length)

So, if the suggestion above does not work, try calling those methods.

Line 320 shows you how to call set_content_length() (and its argument type is on line 319).

lines 124 & 125 show you how to call set_content_type().  In case you are wondering where those arguments come from, look at the #ifdef _MIME_TYPES section of http_constants.dat.  So, you will need:
request.headers().set_content_type(web::http::details::mime_types::application_x_www_form_urlencoded);

Open in new window


>> Note: my environment is Windows 7 with Visual Studio 2015 Community if that helps.
Not at all.  I've never used Visual Studio nor Casablanca :)
Hi Hielo,

BEAUTIFUL!!  Your first suggestion worked perfectly - THANK YOU SOOOOO much!

After I clean my working code up I will post it in full in case it is of use to others but that won't get done for a few hours yet.

I also had to add the include "cpprest/http_headers.h"

Cheers, Eric.
Have posted the 'cleaned-up' code in case it is of interest to someone else.  Did not need the header I mentioned above nor the 'content length' statement.

Again, Hielo's help has been much appreciated.
zzz-post-1.jpg
zzz-post-2.jpg
ASKER CERTIFIED SOLUTION
Avatar of hielo
hielo
Flag of Wallis and Futuna image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial