]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: http-server-ostream - Handle finished request as a separate event.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Thu, 23 Apr 2020 13:21:06 +0000 (15:21 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 27 Apr 2020 17:27:34 +0000 (17:27 +0000)
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.

src/lib-http/http-server-ostream.c
src/lib-http/http-server-private.h
src/lib-http/http-server-request.c
src/lib-http/http-server-response.c

index 58435611650bda436791f04bb75cd52afd979475..77ab60b80577f4415bd1a4edb8bf75df97d6f841 100644 (file)
@@ -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)
 {
index 731bf0b94a1f2b23a9e86ec2d3f14b881e256a29..1d11bb62dbd31eff97f6afd5f8804ee9ff73291b 100644 (file)
@@ -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);
index a5798d99327b5ee5b16c534234aefa4511e36841..315dc9d95d99bdd7a813f53e4791c91bd3f58563 100644 (file)
@@ -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,
index 1680967eec4040149ef538af6731dcdcd3eb6b98..568209da34bced9304bbf529728f468fc0e9b358 100644 (file)
@@ -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;