From: Stephan Bosch Date: Tue, 28 Apr 2020 17:28:48 +0000 (+0200) Subject: lib-http: http-server-response - Fix return value of http_server_response_send*(). X-Git-Tag: 2.3.11.2~123 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e55c179bd0bcafd6059938934b6cd584b75756a;p=thirdparty%2Fdovecot%2Fcore.git lib-http: http-server-response - Fix return value of http_server_response_send*(). Make sure 1 is returned when all that can be sent is sent. It must not return 0 when the payload input stream is blocking or when the payload output stream buffer has no data to be sent. --- diff --git a/src/lib-http/http-server-connection.c b/src/lib-http/http-server-connection.c index 4e741f67cb..86536a30f1 100644 --- a/src/lib-http/http-server-connection.c +++ b/src/lib-http/http-server-connection.c @@ -880,9 +880,7 @@ int http_server_connection_output(struct http_server_connection *conn) if (http_server_connection_unref_is_closed(conn) || ret < 0) return -1; - if (ret > 0) { - i_assert(!conn->output_locked); - + if (!conn->output_locked) { /* Room for more responses */ ret = http_server_connection_send_responses(conn); if (ret < 0) diff --git a/src/lib-http/http-server-ostream.c b/src/lib-http/http-server-ostream.c index 77ab60b805..ec5efd50d8 100644 --- a/src/lib-http/http-server-ostream.c +++ b/src/lib-http/http-server-ostream.c @@ -224,7 +224,7 @@ http_server_ostream_wait_end(struct wrapper_ostream *wostream, http_server_connection_unref(&conn); } -void http_server_ostream_continue(struct http_server_ostream *hsostream) +int http_server_ostream_continue(struct http_server_ostream *hsostream) { struct wrapper_ostream *wostream = &hsostream->wostream; struct http_server_response *resp = hsostream->resp; @@ -234,7 +234,7 @@ void http_server_ostream_continue(struct http_server_ostream *hsostream) i_assert(hsostream->response_destroyed || resp->request->state >= HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT); - wrapper_ostream_continue(wostream); + return wrapper_ostream_continue(wostream); } bool http_server_ostream_get_size(struct http_server_ostream *hsostream, diff --git a/src/lib-http/http-server-private.h b/src/lib-http/http-server-private.h index 1d11bb62db..b6db99f4eb 100644 --- a/src/lib-http/http-server-private.h +++ b/src/lib-http/http-server-private.h @@ -203,7 +203,7 @@ http_server_ostream_create(struct http_server_response *resp, size_t max_buffer_size, bool blocking); bool http_server_ostream_get_size(struct http_server_ostream *hsostream, uoff_t *size_r); -void http_server_ostream_continue(struct http_server_ostream *hsostream); +int http_server_ostream_continue(struct http_server_ostream *hsostream); void http_server_ostream_output_available( struct http_server_ostream *hsostream); diff --git a/src/lib-http/http-server-response.c b/src/lib-http/http-server-response.c index 558d2914ea..72348ac375 100644 --- a/src/lib-http/http-server-response.c +++ b/src/lib-http/http-server-response.c @@ -510,8 +510,7 @@ int http_server_response_send_more(struct http_server_response *resp) if (resp->payload_stream != NULL) { conn->output_locked = TRUE; - http_server_ostream_continue(resp->payload_stream); - return (conn->output_locked ? 0 : 1); + return http_server_ostream_continue(resp->payload_stream); } i_assert(resp->payload_input != NULL); @@ -544,7 +543,7 @@ int http_server_response_send_more(struct http_server_response *resp) http_server_connection_stop_idle_timeout(conn); conn->io_resp_payload = io_add_istream(resp->payload_input, http_server_response_payload_input, resp); - return 0; + return 1; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: /* Output is blocking (client needs to act; enable timeout) */ conn->output_locked = TRUE; @@ -744,10 +743,15 @@ static int http_server_response_send_real(struct http_server_response *resp) } else { /* No payload to send */ e_debug(resp->event, "No payload to send"); - if (resp->payload_stream != NULL) - http_server_ostream_continue(resp->payload_stream); + if (resp->payload_stream != NULL) { + ret = http_server_ostream_continue(resp->payload_stream); + if (ret < 0) + return -1; + } conn->output_locked = FALSE; - http_server_response_finish_payload_out(resp); + ret = http_server_response_finish_payload_out(resp); + if (ret < 0) + return -1; } if (conn->conn.output != NULL && !resp->payload_corked &&