cpprestsdk
cpprestsdk copied to clipboard
Http exception `Failed to write request body` if request is too big.
Colleagues, hello! I have problems with using cpprest in my project caused by size of json that I try to send to server. I realized a small example that indicates the problem:
#include <iostream>
#include <string>
#include <cpprest/json.h>
#include <cpprest/http_client.h>
#include <cpprest/http_listener.h>
#include <cpprest/asyncrt_utils.h>
#include <cpprest/http_msg.h>
using utility::conversions::to_string_t;
int main(int argc, char * argv[]) {
std::cerr << "Hello, cpprest bug example!" << std::endl;
web::http::http_request request = web::http::http_request(web::http::methods::PUT);
web::json::value json;
std::string dataStr = "30 symbols here in this string";
std::string dataStrToSend;
for (int i = 0; i < 100000; i++)
dataStrToSend += dataStr;
json[to_string_t("data")] = web::json::value::string(to_string_t(dataStrToSend));
web::uri dstUri = to_string_t("http://127.0.0.1:7000");
request.set_request_uri(dstUri);
request.set_body(json.serialize(), to_string_t("application/json"));
web::http::client::http_client client(dstUri);
try {
auto future = client.request(request);
web::http::http_response response = future.get();
}
catch (const web::http::http_exception &ex) {
std::cerr << "Http exception occurred. Error code: " << ex.error_code() << " .Reason: `" << ex.what() << '`' << std::endl;
}
catch (const pplx::task_canceled&) {
std::cerr << "Task is canceled." << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Can't create request: " << utility::conversions::to_utf8string(e.what()) << std::endl;
}
catch (...) {
std::cerr << "Unknown exception occurred" << std::endl;
}
std::cerr << "Bye, cpprest bug example!" << std::endl;
return 0;
}
That is my server:
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import ThreadingMixIn
import threading
import json
resp = json.dumps({'reply': {'status': 0, 'message': 'OK'}}).encode('utf-8')
print(resp)
class Handler(BaseHTTPRequestHandler):
def do_PUT(self):
content_len = int(self.headers.get('Content-Length'))
print(self.headers)
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.send_header('Content-Length', str(len(resp)))
self.end_headers()
self.wfile.write(resp)
class ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
pass
def run():
server = ThreadingSimpleServer(('0.0.0.0', 7000), Handler)
server.serve_forever()
if __name__ == '__main__':
run()
So, the exception is thrown...
But! If you reduce the length of dataStrToSend string....
for (int i = 0; i < 1000; i++) dataStrToSend += dataStr;
there are no exceptions.
Also exceptions disappear when you add to server string looking like
self.rfile.read(int(self.headers.get('Content-Length')))
Thanks a lot for your help!
P.S.: As for me it looks like the server is responding before it has received the full request. The same looking like problem discribed at: https://github.com/dakrone/clj-http/issues/277