From: Stephan Bosch Date: Thu, 23 Apr 2020 13:21:06 +0000 (+0200) Subject: lib-http: http-server-ostream - Handle finished request as a separate event. X-Git-Tag: 2.3.11.2~148 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b7f9e8ae11ce2c26cdaadf5bcb13ba5314baed8;p=thirdparty%2Fdovecot%2Fcore.git lib-http: http-server-ostream - Handle finished request as a separate event. While waiting in the flush ioloop, the request will not be destroyed, in which case the ioloop will potentially never end. This is fixed by notifying the wrapper output stream about the parent output stream going away, which interrupts the ioloop in the process. --- diff --git a/src/lib-http/http-server-ostream.c b/src/lib-http/http-server-ostream.c index 5843561165..77ab60b805 100644 --- a/src/lib-http/http-server-ostream.c +++ b/src/lib-http/http-server-ostream.c @@ -295,6 +295,14 @@ http_server_ostream_create(struct http_server_response *resp, blocking, resp->event); } +void http_server_ostream_response_finished( + struct http_server_ostream *hsostream) +{ + e_debug(hsostream->wostream.event, "Response payload finished"); + + wrapper_ostream_output_destroyed(&hsostream->wostream); +} + void http_server_ostream_response_destroyed( struct http_server_ostream *hsostream) { diff --git a/src/lib-http/http-server-private.h b/src/lib-http/http-server-private.h index 731bf0b94a..1d11bb62db 100644 --- a/src/lib-http/http-server-private.h +++ b/src/lib-http/http-server-private.h @@ -207,6 +207,8 @@ void http_server_ostream_continue(struct http_server_ostream *hsostream); void http_server_ostream_output_available( struct http_server_ostream *hsostream); +void http_server_ostream_response_finished( + struct http_server_ostream *hsostream); void http_server_ostream_response_destroyed( struct http_server_ostream *hsostream); @@ -224,6 +226,7 @@ void http_server_response_request_free(struct http_server_response *resp); void http_server_response_request_destroy(struct http_server_response *resp); void http_server_response_request_abort(struct http_server_response *resp, const char *reason); +void http_server_response_request_finished(struct http_server_response *resp); int http_server_response_send(struct http_server_response *resp); int http_server_response_send_more(struct http_server_response *resp); diff --git a/src/lib-http/http-server-request.c b/src/lib-http/http-server-request.c index a5798d9932..315dc9d95d 100644 --- a/src/lib-http/http-server-request.c +++ b/src/lib-http/http-server-request.c @@ -410,6 +410,9 @@ void http_server_request_finished(struct http_server_request *req) http_server_connection_remove_request(conn, req); conn->stats.response_count++; + if (req->response != NULL) + http_server_response_request_finished(req->response); + if (tunnel_callback == NULL) { if (req->connection_close) { http_server_connection_close(&conn, diff --git a/src/lib-http/http-server-response.c b/src/lib-http/http-server-response.c index 1680967eec..568209da34 100644 --- a/src/lib-http/http-server-response.c +++ b/src/lib-http/http-server-response.c @@ -323,6 +323,14 @@ http_server_response_flush_payload(struct http_server_response *resp) return 1; } +void http_server_response_request_finished(struct http_server_response *resp) +{ + e_debug(resp->event, "Finished"); + + if (resp->payload_stream != NULL) + http_server_ostream_response_finished(resp->payload_stream); +} + int http_server_response_finish_payload_out(struct http_server_response *resp) { struct http_server_request *req = resp->request;