From: Stephan Bosch Date: Sat, 9 Nov 2019 10:02:56 +0000 (+0100) Subject: lib-http: http-server-connection - Add internal API for halting and resuming connecti... X-Git-Tag: 2.3.11.2~274 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4dbc82ffda7feb93f31b3bbac3f14a4ab2537646;p=thirdparty%2Fdovecot%2Fcore.git lib-http: http-server-connection - Add internal API for halting and resuming connection output handling. --- diff --git a/src/lib-http/http-server-connection.c b/src/lib-http/http-server-connection.c index c594ed0d49..8b90be9885 100644 --- a/src/lib-http/http-server-connection.c +++ b/src/lib-http/http-server-connection.c @@ -314,7 +314,7 @@ http_server_connection_handle_request(struct http_server_connection *conn, /* Send 100 Continue when appropriate */ if (req->req.expect_100_continue && !req->payload_halted && req->response == NULL) { - http_server_connection_trigger_responses(conn); + http_server_connection_output_trigger(conn); } /* Delegate payload handling to request handler */ @@ -988,12 +988,32 @@ int http_server_connection_output(struct http_server_connection *conn) return 1; } -void http_server_connection_trigger_responses( - struct http_server_connection *conn) +void http_server_connection_output_trigger(struct http_server_connection *conn) { + if (conn->conn.output == NULL) + return; o_stream_set_flush_pending(conn->conn.output, TRUE); } +void http_server_connection_output_halt(struct http_server_connection *conn) +{ + conn->output_halted = TRUE; + + if (conn->conn.output == NULL) + return; + + o_stream_unset_flush_callback(conn->conn.output); +} + +void http_server_connection_output_resume(struct http_server_connection *conn) +{ + if (conn->output_halted) { + conn->output_halted = FALSE; + o_stream_set_flush_callback(conn->conn.output, + http_server_connection_output, conn); + } +} + bool http_server_connection_pending_payload( struct http_server_connection *conn) { diff --git a/src/lib-http/http-server-private.h b/src/lib-http/http-server-private.h index 82fad79022..c2dde79fa1 100644 --- a/src/lib-http/http-server-private.h +++ b/src/lib-http/http-server-private.h @@ -156,6 +156,7 @@ struct http_server_connection { bool close_indicated:1; bool input_broken:1; bool output_locked:1; + bool output_halted:1; bool in_req_callback:1; /* performing request callback (busy) */ }; @@ -279,8 +280,10 @@ bool http_server_connection_shut_down(struct http_server_connection *conn); void http_server_connection_handle_output_error( struct http_server_connection *conn); -void http_server_connection_trigger_responses( - struct http_server_connection *conn); +void http_server_connection_output_trigger(struct http_server_connection *conn); +void http_server_connection_output_halt(struct http_server_connection *conn); +void http_server_connection_output_resume(struct http_server_connection *conn); + int http_server_connection_flush(struct http_server_connection *conn); int http_server_connection_output(struct http_server_connection *conn); diff --git a/src/lib-http/http-server-request.c b/src/lib-http/http-server-request.c index c5c31300b7..5688f78886 100644 --- a/src/lib-http/http-server-request.c +++ b/src/lib-http/http-server-request.c @@ -257,7 +257,7 @@ void http_server_request_continue_payload(struct http_server_request *req) i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED); req->payload_halted = FALSE; if (req->req.expect_100_continue && !req->sent_100_continue) - http_server_connection_trigger_responses(req->conn); + http_server_connection_output_trigger(req->conn); } static void @@ -325,7 +325,7 @@ void http_server_request_ready_to_respond(struct http_server_request *req) e_debug(req->event, "Ready to respond"); req->state = HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND; - http_server_connection_trigger_responses(req->conn); + http_server_connection_output_trigger(req->conn); } void http_server_request_submit_response(struct http_server_request *req) @@ -354,7 +354,7 @@ void http_server_request_submit_response(struct http_server_request *req) http_server_request_ready_to_respond(req); break; case HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND: - http_server_connection_trigger_responses(req->conn); + http_server_connection_output_trigger(req->conn); break; case HTTP_SERVER_REQUEST_STATE_ABORTED: break; @@ -408,7 +408,7 @@ void http_server_request_finished(struct http_server_request *req) return; } - http_server_connection_trigger_responses(conn); + http_server_connection_output_trigger(conn); } static struct http_server_response * @@ -593,7 +593,7 @@ http_server_istream_read(struct istream_private *stream) if (blocking && req->req.expect_100_continue && !req->sent_100_continue) - http_server_connection_trigger_responses(conn); + http_server_connection_output_trigger(conn); hsristream->read_status = 0; io = io_add_istream(&stream->istream, diff --git a/src/lib-http/http-server-response.c b/src/lib-http/http-server-response.c index 242c534f80..e10594dad6 100644 --- a/src/lib-http/http-server-response.c +++ b/src/lib-http/http-server-response.c @@ -392,7 +392,7 @@ http_server_response_output_payload(struct http_server_response **_resp, if (req->state < HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT) { e_debug(resp->event, "Preparing to send blocking payload"); - http_server_connection_trigger_responses(conn); + http_server_connection_output_trigger(conn); } else if (resp->payload_output != NULL) { e_debug(resp->event, "Sending blocking payload");