drogon
drogon copied to clipboard
fails to respond when the data size is extra large (1M or larger)
Describe the bug
When returning a large value from a HttpController, the server stucks into an infinite loop, showing the message below on the console.
(Maybe this is a bug of trantor)
20210211 16:27:43.975639 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975643 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975649 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975652 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975657 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975660 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975666 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975669 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975674 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975677 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975683 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
20210211 16:27:43.975686 UTC 1171326 DEBUG [writeCallback] EPIPE or ECONNRESET, erron=32 - TcpConnectionImpl.cc:489
...
To Reproduce
- create a post request
- send a large size array json
- just return the request json
void some_controller::index(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback) {
auto resp = HttpResponse::newHttpResponse();
resp->setStatusCode(k200OK);
resp->setBody(req->bodyData());
callback(resp);
}
Desktop (please complete the following information):
- Mac OSX 10.15.7 (Catalina)
- clang 12.0.0
Hi, I can't reproduce the issue on my MacOS (with the same version of OS and compiler), are any other conditions missed? Would you like to give me more info? Thanks.
Are the client and the server on the same host? What is the client used to send large requests?
The client is on localhost:8080 and the drogon server is on localhost:8081. I set the request with fetch function of javascript:
const res = await fetch(origin + urlString, {
method: this.method,
body: params.body ? JSON.stringify(params.body) : undefined,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
mode: 'no-cors',
...params.query
}).then(async r => r.json())
Did u use the latest version of drogon?
I used Postman to send requests with a 1.8M body. it works as expected.
Did u use the latest version of drogon?
I re-installed drogon and updated to the latest version but the issue remains...
When I used the cURL command, somehow the request succeeds. It seems that this problem is specific to requests from browsers.
Please give me an HTML page with js code that can reproduce the issue. Thanks.
Using no-cors with fetch doesn't allow application/json as the content type. It allows the content type header but only for application/x-www-form-urlencoded, multipart/form-data, or text/plain.
Additionally, Access-Control-Allow-Origin must come in the response from the server, not in the request payload. In a typical CORS request the request contains an Origin header. The server inspects this and decides if it wants to trust it and responds with a Access-Control-Allow-Origin header typically with a * as the value.
See: https://javascript.info/fetch-crossorigin#cors-for-safe-requests https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#supplying_request_options
Just to clarify on my previous comment, there is no issue with drogon here, the issue is with the default behaviour of the fetch API.