Skip to content

Commit 72d6651

Browse files
crjcJay
andauthored
Read body in parseRequest for HttpServer (#244)
Co-authored-by: Jay <[email protected]>
1 parent a4e5d1b commit 72d6651

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

ixwebsocket/IXHttp.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,28 @@ namespace ix
129129
{
130130
return std::make_tuple(false, "Error parsing HTTP headers", httpRequest);
131131
}
132+
133+
std::string body = "";
134+
if (headers.find("Content-Length") != headers.end()){
135+
136+
int contentLength = 0;
137+
try {
138+
contentLength = std::stoi(headers["Content-Length"]);
139+
}
140+
catch (std::exception){
141+
return std::make_tuple(false, "Error parsing HTTP Header 'Content-Length'", httpRequest);
142+
}
143+
144+
char c;
145+
body.reserve(contentLength);
146+
147+
for (int i = 0; i < contentLength; i++){
148+
if (socket->readByte(&c, isCancellationRequested))
149+
body += c;
150+
}
151+
}
132152

133-
httpRequest = std::make_shared<HttpRequest>(uri, method, httpVersion, headers);
153+
httpRequest = std::make_shared<HttpRequest>(uri, method, httpVersion, body, headers);
134154
return std::make_tuple(true, "", httpRequest);
135155
}
136156

ixwebsocket/IXHttp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,18 @@ namespace ix
9595
std::string uri;
9696
std::string method;
9797
std::string version;
98+
std::string body;
9899
WebSocketHttpHeaders headers;
99100

100101
HttpRequest(const std::string& u,
101102
const std::string& m,
102103
const std::string& v,
104+
const std::string& b,
103105
const WebSocketHttpHeaders& h = WebSocketHttpHeaders())
104106
: uri(u)
105107
, method(m)
106108
, version(v)
109+
, body(b)
107110
, headers(h)
108111
{
109112
}

test/IXHttpServerTest.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,51 @@ TEST_CASE("http server", "[httpd]")
6363

6464
server.stop();
6565
}
66+
67+
SECTION("Posting plain text data to a local HTTP server")
68+
{
69+
int port = getFreePort();
70+
ix::HttpServer server(port, "127.0.0.1");
71+
72+
server.setOnConnectionCallback([](HttpRequestPtr request, std::shared_ptr<ConnectionState>) -> HttpResponsePtr {
73+
if (request->method == "POST"){
74+
return std::make_shared<HttpResponse>(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), request->body);
75+
}
76+
77+
return std::make_shared<HttpResponse>(400, "BAD REQUEST");
78+
});
79+
80+
auto res = server.listen();
81+
REQUIRE(res.first);
82+
server.start();
83+
84+
HttpClient httpClient;
85+
WebSocketHttpHeaders headers;
86+
headers["Content-Type"] = "text/plain";
87+
88+
std::string url("http://127.0.0.1:");
89+
url += std::to_string(port);
90+
auto args = httpClient.createRequest(url);
91+
92+
args->extraHeaders = headers;
93+
args->connectTimeout = 60;
94+
args->transferTimeout = 60;
95+
args->verbose = true;
96+
args->logger = [](const std::string& msg) { std::cout << msg; };
97+
args->body = "Hello World!";
98+
99+
auto response = httpClient.post(url, args->body, args);
100+
101+
std::cerr << "Status: " << response->statusCode << std::endl;
102+
std::cerr << "Error message: " << response->errorMsg << std::endl;
103+
std::cerr << "Payload: " << response->payload << std::endl;
104+
105+
REQUIRE(response->errorCode == HttpErrorCode::Ok);
106+
REQUIRE(response->statusCode == 200);
107+
REQUIRE(response->payload == args->body);
108+
109+
server.stop();
110+
}
66111
}
67112

68113
TEST_CASE("http server redirection", "[httpd_redirect]")

0 commit comments

Comments
 (0)