I have a http client that I wrote in python in tornado framework:
http_client = httpclient.HTTPClient()
request = httpclient.HTTPRequest("http://127.0.0.1:8000", method='PUT', body=str("data"))
response = http_client.fetch(request)
on the other side I have an asynchronous server that I wrote in c++ using cpp-netlib. It basically has to read the request and print its body
class Server;
typedef http::async_server<Server> server;
class Server {
public:
void operator()(server::request const & request, server::connection_ptr connection)
{
boost::shared_ptr<connection_handler> h(new connection_handler());
(*h)(request, connection);
server::response_header headers[] = { {"Connection","close"} ,{"Content-Type", "text/plain"} };
connection->set_headers(boost::make_iterator_range(headers, headers+2));
connection->set_status(server::connection::accepted);
connection->write("helloworld");
}
int main()
{
Server handler;
server::options options(handler);
server instance(
options.thread_pool(boost::make_shared<utils::thread_pool>(5))
.address("0.0.0.0")
.port("8000"));
instance.run();
return 0;
}
and the connection handler looks like this:
struct connection_handler : boost::enable_shared_from_this<connection_handler>
{
struct read_post_callback
{
typedef boost::shared_ptr<connection_handler> handler_ptr_t;
read_post_callback(handler_ptr_t handler_ptr) : handler(handler_ptr) {}
void operator()(server::connection::input_range range, boost::system::error_code error, size_t size, server::connection_ptr conn)
{
handler->read_sofar += size;
handler->cond.notify_one();
}
handler_ptr_t handler;
};
void operator()(server::request const &req, server::connection_ptr conn)
{
int cl;
server::request::headers_container_type const &hs = req.headers;
for(server::request::headers_container_type::const_iterator it = hs.begin(); it!=hs.end(); ++it)
{
if(boost::to_lower_copy(it->name)=="content-length")
{
cl = boost::lexical_cast<int>(it->value);
break;
}
}
cout<< req.body << endl;
read_sofar = 0;
while(read_sofar<cl)
{
boost::unique_lock<boost::mutex> lock(mtx);
server::connection::read_callback_function cc = read_post_callback(shared_from_this());
conn->read(cc);
cond.wait(lock);
}
}
int read_sofar;
boost::condition_variable cond;
boost::mutex mtx;
};
But request body is always empty and instead of the response I send back ("hello world") most of the time I get something like this (the number could be different)
Error: HTTP 0: Unknown
Can you tell me why the body is empty or why the response doesn't reach?
EDIT:
Why the body was empty is in the answer. What I was doing wrong that I wouldn't receive the response was this: I was setting the connection status after setting connection headers in my server. Just swapped their order and it worked like a charm.
server::response_header headers[] = { {"Connection","close"} ,{"Content-Type", "text/plain"} };
connection->set_status(server::connection::accepted);
connection->set_headers(boost::make_iterator_range(headers, headers+2));
connection->write("helloworld");