Mercurial > dovecot > core-2.2
changeset 19727:8f72e4f0ed5d
lib-http: client: Fixed pipelining bug: client sometimes sent new request while still waiting for 100-continue.
author | Stephan Bosch <stephan@rename-it.nl> |
---|---|
date | Mon, 08 Feb 2016 22:47:30 +0100 |
parents | f40f5e721744 |
children | ea58eba051b5 |
files | src/lib-http/http-client-connection.c src/lib-http/http-client-private.h src/lib-http/http-client-request.c |
diffstat | 3 files changed, 12 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-http/http-client-connection.c Mon Feb 08 22:45:54 2016 +0100 +++ b/src/lib-http/http-client-connection.c Mon Feb 08 22:47:30 2016 +0100 @@ -369,7 +369,7 @@ array_count(&conn->request_wait_list)-1); req = req_idx[0]; - conn->payload_continue = TRUE; + req->payload_sync_continue = TRUE; if (http_client_request_send_more(req, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, @@ -401,7 +401,7 @@ timeout_remove(&conn->to_idle); req->conn = conn; - conn->payload_continue = FALSE; + req->payload_sync_continue = FALSE; if (conn->peer->no_payload_sync) req->payload_sync = FALSE; @@ -742,7 +742,7 @@ user agent MAY ignore unexpected 1xx responses. */ if (req->payload_sync && response.status == 100) { - if (conn->payload_continue) { + if (req->payload_sync_continue) { http_client_connection_debug(conn, "Got 100-continue response after timeout"); continue; @@ -750,7 +750,7 @@ conn->peer->no_payload_sync = FALSE; conn->peer->seen_100_response = TRUE; - conn->payload_continue = TRUE; + req->payload_sync_continue = TRUE; http_client_connection_debug(conn, "Got expected 100-continue response"); @@ -792,8 +792,10 @@ timeval_diff_msecs(&req->sent_time, &req->submit_time)); /* make sure connection output is unlocked if 100-continue failed */ - if (req->payload_sync && !conn->payload_continue) - conn->output_locked = FALSE; + if (req->payload_sync && !req->payload_sync_continue) { + http_client_connection_debug(conn, "Unlocked output"); + conn->output_locked = FALSE; + } /* remove request from queue */ array_delete(&conn->request_wait_list, 0, 1); @@ -822,7 +824,7 @@ blocks via http_client_request_send_payload() and we're not waiting for 100 continue */ if (!req->payload_wait || - (req->payload_sync && !conn->payload_continue)) { + (req->payload_sync && !req->payload_sync_continue)) { /* failed Expect: */ if (response.status == 417 && req->payload_sync) { /* drop Expect: continue */ @@ -971,7 +973,7 @@ return 1; } - if (!req->payload_sync || conn->payload_continue) { + if (!req->payload_sync || req->payload_sync_continue) { if (http_client_request_send_more(req, &error) < 0) { http_client_connection_abort_temp_error(&conn, HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
--- a/src/lib-http/http-client-private.h Mon Feb 08 22:45:54 2016 +0100 +++ b/src/lib-http/http-client-private.h Mon Feb 08 22:47:30 2016 +0100 @@ -115,6 +115,7 @@ unsigned int have_hdr_user_agent:1; unsigned int payload_sync:1; + unsigned int payload_sync_continue:1; unsigned int payload_chunked:1; unsigned int payload_wait:1; unsigned int urgent:1; @@ -160,8 +161,6 @@ unsigned int close_indicated:1; unsigned int output_locked:1; /* output is locked; no pipelining */ unsigned int output_broken:1; /* output is broken; no more requests */ - unsigned int payload_continue:1; /* received 100-continue for current - request */ unsigned int in_req_callback:1; /* performin request callback (busy) */ };
--- a/src/lib-http/http-client-request.c Mon Feb 08 22:45:54 2016 +0100 +++ b/src/lib-http/http-client-request.c Mon Feb 08 22:47:30 2016 +0100 @@ -1239,7 +1239,7 @@ 100 continue (there's no way to rewind the payload for a retry) */ if (req->payload_wait && - (!req->payload_sync || req->conn->payload_continue)) + (!req->payload_sync || req->payload_sync_continue)) return FALSE; /* limit the number of attempts for each request */ if (req->attempts+1 >= req->client->set.max_attempts)