diff --git a/mongoose.c b/mongoose.c index 50203103..2e42b5aa 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2853,7 +2853,6 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm, etag, (uint64_t) cl, gzip ? "Content-Encoding: gzip\r\n" : "", range, opts->extra_headers ? opts->extra_headers : ""); if (mg_strcasecmp(hm->method, mg_str("HEAD")) == 0) { - c->is_draining = 1; c->is_resp = 0; mg_fs_close(fd); } else { @@ -3216,7 +3215,9 @@ static int skip_chunk(const char *buf, int len, int *pl, int *dl) { } static void http_cb(struct mg_connection *c, int ev, void *ev_data) { - if (ev == MG_EV_READ || ev == MG_EV_CLOSE) { + if (ev == MG_EV_READ || ev == MG_EV_CLOSE || + (ev == MG_EV_POLL && c->is_accepted && !c->is_draining && + c->recv.len > 0)) { // see #2796 struct mg_http_message hm; size_t ofs = 0; // Parsing offset while (c->is_resp == 0 && ofs < c->recv.len) { diff --git a/src/http.c b/src/http.c index cb8013f1..dcbfdd81 100644 --- a/src/http.c +++ b/src/http.c @@ -637,7 +637,6 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm, etag, (uint64_t) cl, gzip ? "Content-Encoding: gzip\r\n" : "", range, opts->extra_headers ? opts->extra_headers : ""); if (mg_strcasecmp(hm->method, mg_str("HEAD")) == 0) { - c->is_draining = 1; c->is_resp = 0; mg_fs_close(fd); } else { @@ -1000,7 +999,9 @@ static int skip_chunk(const char *buf, int len, int *pl, int *dl) { } static void http_cb(struct mg_connection *c, int ev, void *ev_data) { - if (ev == MG_EV_READ || ev == MG_EV_CLOSE) { + if (ev == MG_EV_READ || ev == MG_EV_CLOSE || + (ev == MG_EV_POLL && c->is_accepted && !c->is_draining && + c->recv.len > 0)) { // see #2796 struct mg_http_message hm; size_t ofs = 0; // Parsing offset while (c->is_resp == 0 && ofs < c->recv.len) { diff --git a/test/unit_test.c b/test/unit_test.c index 98e39b6d..a816520d 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -923,9 +923,9 @@ static void test_http_server(void) { // Pipelined requests ASSERT(fpr(&mgr, buf, url, "GET /foo/bar HTTP/1.1\n\nGET /foo/foobar HTTP/1.1\n\n") == 2); - // Pipelined requests with files (see #2796) - //ASSERT(fpr(&mgr, buf, url, "GET /a.txt HTTP/1.1\n\nGET /a.txt HTTP/1.1\n\n") == 2); - //ASSERT(fpr(&mgr, buf, url, "HEAD /a.txt HTTP/1.1\n\nGET /a.txt HTTP/1.1\n\n") == 2); + // Pipelined requests with file requests other than the last one (see #2796) + ASSERT(fpr(&mgr, buf, url, "GET /a.txt HTTP/1.1\n\nGET /a.txt HTTP/1.1\n\n") == 2); + ASSERT(fpr(&mgr, buf, url, "HEAD /a.txt HTTP/1.1\n\nGET /a.txt HTTP/1.1\n\n") == 2); // Connection: close ASSERT(fpr(&mgr, buf, url, "GET /foo/bar HTTP/1.1\nConnection: close\n\nGET /foo/foobar HTTP/1.1\n\n") == 1); ASSERT(cmpbody(buf, "uri: bar") == 0);