]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: client: Fixed aborting request in the middle of sending payload.
authorStephan Bosch <stephan@rename-it.nl>
Wed, 1 Oct 2014 07:33:39 +0000 (10:33 +0300)
committerStephan Bosch <stephan@rename-it.nl>
Wed, 1 Oct 2014 07:33:39 +0000 (10:33 +0300)
If the request payload is so big that it cannot be sent all at once, the
caller may at some point abort the request when it is still being sent. The
bug occurred when the request finally finished sending. It erroneously
advanced the state to WAITING rather than remaining ABORTED, thus
'reviving' the request unexpectedly.

src/lib-http/http-client-connection.c
src/lib-http/http-client-request.c

index 0dfd45854275ffd6ae21aef390ba4c6cdbf74fcd..4a0d37de6666c014c1df93f39a97904cd5142ecb 100644 (file)
@@ -299,6 +299,7 @@ int http_client_connection_next_request(struct http_client_connection *conn)
        if (conn->peer->no_payload_sync)
                req->payload_sync = FALSE;
 
+       i_assert(req->state == HTTP_REQUEST_STATE_QUEUED);
        array_append(&conn->request_wait_list, &req, 1);
        http_client_request_ref(req);
 
index 0069d8936248c8ddddbbf92fa4aea9cffc1faec0..2e3ac4bb2c55d49698a0c5598268c7448e538461 100644 (file)
@@ -453,14 +453,23 @@ http_client_request_finish_payload_out(struct http_client_request *req)
 {
        i_assert(req->conn != NULL);
 
+       /* drop payload output stream */
        if (req->payload_output != NULL) {
                o_stream_unref(&req->payload_output);
                req->payload_output = NULL;
        }
-       req->state = HTTP_REQUEST_STATE_WAITING;
+
+       /* advance state only when request didn't get aborted in the mean time */
+       if (req->state != HTTP_REQUEST_STATE_ABORTED) {
+               i_assert(req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT);
+               req->state = HTTP_REQUEST_STATE_WAITING;
+       }
+
+       /* release connection */
        req->conn->output_locked = FALSE;
 
-       http_client_request_debug(req, "Finished sending payload");
+       http_client_request_debug(req, "Finished sending%s payload",
+               (req->state == HTTP_REQUEST_STATE_ABORTED ? " aborted" : ""));
 }
 
 static int