mirror of
https://github.com/cesanta/mongoose.git
synced 2025-06-21 02:50:47 +08:00
Fix handling of keepalive HTTP requests/responses
Clean the HTTP connection state when ia request/response has been fully buffered and handler invoked. Fixes https://github.com/cesanta/mongoose/issues/971 CL: mg: Fix handling of keepalive HTTP requests/responses PUBLISHED_FROM=70c854aa306aacb9161f6ee48841f38dc0312e6b
This commit is contained in:
parent
492b8f6950
commit
05c687e251
21
mongoose.c
21
mongoose.c
@ -6616,6 +6616,7 @@ void mg_http_handler(struct mg_connection *nc, int ev,
|
||||
}
|
||||
} else {
|
||||
/* We did receive all HTTP body. */
|
||||
int request_done = 1;
|
||||
int trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY;
|
||||
char addr[32];
|
||||
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
||||
@ -6627,12 +6628,32 @@ void mg_http_handler(struct mg_connection *nc, int ev,
|
||||
mg_http_call_endpoint_handler(nc, trigger_ev, hm);
|
||||
mbuf_remove(io, hm->message.len);
|
||||
pd->rcvd -= hm->message.len;
|
||||
#if MG_ENABLE_FILESYSTEM
|
||||
/* We don't have a generic mechanism of communicating that we are done
|
||||
* responding to a request (should probably add one). But if we are
|
||||
* serving
|
||||
* a file, we are definitely not done. */
|
||||
if (pd->file.fp != NULL) request_done = 0;
|
||||
#endif
|
||||
#if MG_ENABLE_HTTP_CGI
|
||||
/* If this is a CGI request, we are not done either. */
|
||||
if (pd->cgi.cgi_nc != NULL) request_done = 0;
|
||||
#endif
|
||||
if (request_done) {
|
||||
/* This request is done but we may receive another on this connection.
|
||||
*/
|
||||
mg_http_conn_destructor(pd);
|
||||
nc->proto_data = NULL;
|
||||
if (io->len > 0) {
|
||||
/* We already have data for the next one, restart parsing. */
|
||||
pd = mg_http_get_proto_data(nc);
|
||||
pd->rcvd = io->len;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t mg_get_line_len(const char *buf, size_t buf_len) {
|
||||
size_t len = 0;
|
||||
|
@ -869,6 +869,7 @@ void mg_http_handler(struct mg_connection *nc, int ev,
|
||||
}
|
||||
} else {
|
||||
/* We did receive all HTTP body. */
|
||||
int request_done = 1;
|
||||
int trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY;
|
||||
char addr[32];
|
||||
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
|
||||
@ -880,12 +881,32 @@ void mg_http_handler(struct mg_connection *nc, int ev,
|
||||
mg_http_call_endpoint_handler(nc, trigger_ev, hm);
|
||||
mbuf_remove(io, hm->message.len);
|
||||
pd->rcvd -= hm->message.len;
|
||||
#if MG_ENABLE_FILESYSTEM
|
||||
/* We don't have a generic mechanism of communicating that we are done
|
||||
* responding to a request (should probably add one). But if we are
|
||||
* serving
|
||||
* a file, we are definitely not done. */
|
||||
if (pd->file.fp != NULL) request_done = 0;
|
||||
#endif
|
||||
#if MG_ENABLE_HTTP_CGI
|
||||
/* If this is a CGI request, we are not done either. */
|
||||
if (pd->cgi.cgi_nc != NULL) request_done = 0;
|
||||
#endif
|
||||
if (request_done) {
|
||||
/* This request is done but we may receive another on this connection.
|
||||
*/
|
||||
mg_http_conn_destructor(pd);
|
||||
nc->proto_data = NULL;
|
||||
if (io->len > 0) {
|
||||
/* We already have data for the next one, restart parsing. */
|
||||
pd = mg_http_get_proto_data(nc);
|
||||
pd->rcvd = io->len;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t mg_get_line_len(const char *buf, size_t buf_len) {
|
||||
size_t len = 0;
|
||||
|
@ -2069,7 +2069,7 @@ static const char *test_http(void) {
|
||||
nc->user_data = mime2;
|
||||
|
||||
/* Run event loop. Use more cycles to let file download complete. */
|
||||
poll_until(&mgr, 5, c_str_ne, status, (void *) "");
|
||||
poll_until(&mgr, 15, c_str_ne, status, (void *) "");
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
/* Check that test buffer has been filled by the callback properly. */
|
||||
|
Loading…
Reference in New Issue
Block a user