Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BOOST ASIO POST HTTP REQUEST -- headers and body

I've been trying to get this to work for a couple of days however I keep getting a 400 error from the server.

Basically, what I'm trying to do is send a http POST request to a server that requires a JSON request body with a couple of properties.

These are the libs I'm currently using

UPDATED --- 7/23/13 10:00am just noticed I'm using TCP instead of HTTP not sure how much this will effect an HTTP call but i can't find any examples of clients using pure HTTP with BOOST::ASIO

#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>

#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

using boost::property_tree::ptree; using boost::property_tree::read_json; using boost::property_tree::write_json;

using boost::asio::ip::tcp;

SET UP CODE

    // Get a list of endpoints corresponding to the server name.
tcp::resolver resolver(io_service);
tcp::resolver::query query(part1, "http");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

// Try each endpoint until we successfully establish a connection.
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);

// Form the request. We specify the "Connection: close" header so that the
// server will close the socket after transmitting the response. This will
// allow us to treat all data up until the EOF as the content.
boost::asio::streambuf request;
std::ostream request_stream(&request);

JSON BODY

ptree root, info;
root.put ("some value", "8");
root.put ( "message", "value value: value!");
info.put("placeholder", "value");
info.put("value", "daf!");
info.put("module", "value");
root.put_child("exception", info);

std::ostringstream buf; 
write_json (buf, root, false);
std::string json = buf.str();

HEADER AND CONNECTION REQUEST

request_stream << "POST /title/ HTTP/1.1 \r\n";
request_stream << "Host:" << some_host << "\r\n";
request_stream << "User-Agent: C/1.0";
request_stream << "Content-Type: application/json; charset=utf-8 \r\n";
request_stream << json << "\r\n";
request_stream << "Accept: */*\r\n";    
request_stream << "Connection: close\r\n\r\n";

// Send the request.
boost::asio::write(socket, request);

I put place holder values however if you see anything that doesn't work in my code that jumps out please let me know I have no idea why i keep getting a 400, bad request.

info about the rig

C++

WIN7

VISUAL STUDIO

like image 408
progrenhard Avatar asked Jul 22 '13 23:07

progrenhard


1 Answers

Although this question is very old I would like to post this answer for users who are facing similar problem for http POST.

The server is sending you HTTP 400 means "BAD REQUEST". It is because the way you are forming your request is bit wrong.

The following is the correct way to send the POST request containing JSON data.

#include<string>  //for length()

request_stream << "POST /title/ HTTP/1.1 \r\n";
request_stream << "Host:" << some_host << "\r\n";
request_stream << "User-Agent: C/1.0\r\n";
request_stream << "Content-Type: application/json; charset=utf-8 \r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Content-Length: " << json.length() << "\r\n";    
request_stream << "Connection: close\r\n\r\n";  //NOTE THE Double line feed
request_stream << json;

Whenever you are sending any data(json,string etc) with your POST request, make sure:

(1) Content-Length: is accurate.

(2) that you put the Data at the end of your request with a line gap.

(3) and for that (2nd point) to happen you MUST provide double line feed (i.e. \r\n\r\n) in the last header of your header request. This tells the header that HTTP request content is over and now it(server) will get the data.

If you don't do this then the server fails to understand that where the header is ending ? and where the data is beginning ? So, it keeps waiting for the promised data (it hangs).

Disclaimer: Feel free to edit for inaccuracies, if any.

like image 129
K.K Avatar answered Oct 13 '22 16:10

K.K