diff --git a/ixwebsocket/IXHttp.cpp b/ixwebsocket/IXHttp.cpp index 0f858ac2..62c60422 100644 --- a/ixwebsocket/IXHttp.cpp +++ b/ixwebsocket/IXHttp.cpp @@ -129,8 +129,28 @@ namespace ix { return std::make_tuple(false, "Error parsing HTTP headers", httpRequest); } + + std::string body = ""; + if (headers.find("Content-Length") != headers.end()){ + + int contentLength = 0; + try { + contentLength = std::stoi(headers["Content-Length"]); + } + catch (std::exception){ + return std::make_tuple(false, "Error parsing HTTP Header 'Content-Length'", httpRequest); + } + + char c; + body.reserve(contentLength); + + for (int i = 0; i < contentLength; i++){ + if (socket->readByte(&c, isCancellationRequested)) + body += c; + } + } - httpRequest = std::make_shared(uri, method, httpVersion, headers); + httpRequest = std::make_shared(uri, method, httpVersion, body, headers); return std::make_tuple(true, "", httpRequest); } diff --git a/ixwebsocket/IXHttp.h b/ixwebsocket/IXHttp.h index 71a0db69..1d8807a7 100644 --- a/ixwebsocket/IXHttp.h +++ b/ixwebsocket/IXHttp.h @@ -95,15 +95,18 @@ namespace ix std::string uri; std::string method; std::string version; + std::string body; WebSocketHttpHeaders headers; HttpRequest(const std::string& u, const std::string& m, const std::string& v, + const std::string& b, const WebSocketHttpHeaders& h = WebSocketHttpHeaders()) : uri(u) , method(m) , version(v) + , body(b) , headers(h) { } diff --git a/test/IXHttpServerTest.cpp b/test/IXHttpServerTest.cpp index 39833b3d..bbdb3295 100644 --- a/test/IXHttpServerTest.cpp +++ b/test/IXHttpServerTest.cpp @@ -63,6 +63,51 @@ TEST_CASE("http server", "[httpd]") server.stop(); } + + SECTION("Posting plain text data to a local HTTP server") + { + int port = getFreePort(); + ix::HttpServer server(port, "127.0.0.1"); + + server.setOnConnectionCallback([](HttpRequestPtr request, std::shared_ptr) -> HttpResponsePtr { + if (request->method == "POST"){ + return std::make_shared(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), request->body); + } + + return std::make_shared(400, "BAD REQUEST"); + }); + + auto res = server.listen(); + REQUIRE(res.first); + server.start(); + + HttpClient httpClient; + WebSocketHttpHeaders headers; + headers["Content-Type"] = "text/plain"; + + std::string url("http://127.0.0.1:"); + url += std::to_string(port); + auto args = httpClient.createRequest(url); + + args->extraHeaders = headers; + args->connectTimeout = 60; + args->transferTimeout = 60; + args->verbose = true; + args->logger = [](const std::string& msg) { std::cout << msg; }; + args->body = "Hello World!"; + + auto response = httpClient.post(url, args->body, args); + + std::cerr << "Status: " << response->statusCode << std::endl; + std::cerr << "Error message: " << response->errorMsg << std::endl; + std::cerr << "Payload: " << response->payload << std::endl; + + REQUIRE(response->errorCode == HttpErrorCode::Ok); + REQUIRE(response->statusCode == 200); + REQUIRE(response->payload == args->body); + + server.stop(); + } } TEST_CASE("http server redirection", "[httpd_redirect]")