Mercurial > dovecot > core-2.2
changeset 17052:353c3e3edc52
lib-http: Don't try to automatically retry requests whose payload was already lost.
Patch by Stephan Bosch.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 08 Dec 2013 23:41:33 +0200 |
parents | 7acfc7b1b8f4 |
children | 7a7898ffe87f |
files | src/lib-http/http-client-connection.c src/lib-http/http-client-request.c |
diffstat | 2 files changed, 50 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-http/http-client-connection.c Sun Dec 08 23:26:40 2013 +0200 +++ b/src/lib-http/http-client-connection.c Sun Dec 08 23:41:33 2013 +0200 @@ -596,31 +596,37 @@ if (!aborted) { bool handled = FALSE; - /* failed Expect: */ - if (response.status == 417 && req->payload_sync) { - /* drop Expect: continue */ - req->payload_sync = FALSE; - conn->output_locked = FALSE; - conn->peer->no_payload_sync = TRUE; - if (http_client_request_try_retry(req)) - handled = TRUE; - /* redirection */ - } else if (!req->client->set.no_auto_redirect && - response.status / 100 == 3 && response.status != 304 && - response.location != NULL) { - /* redirect (possibly after delay) */ - if (http_client_request_delay_from_response(req, &response) >= 0) { - http_client_request_redirect - (req, response.status, response.location); - handled = TRUE; + /* don't redirect/retry if we're sending data in small + 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)) { + /* failed Expect: */ + if (response.status == 417 && req->payload_sync) { + /* drop Expect: continue */ + req->payload_sync = FALSE; + conn->output_locked = FALSE; + conn->peer->no_payload_sync = TRUE; + if (http_client_request_try_retry(req)) + handled = TRUE; + /* redirection */ + } else if (!req->client->set.no_auto_redirect && + response.status / 100 == 3 && response.status != 304 && + response.location != NULL) { + /* redirect (possibly after delay) */ + if (http_client_request_delay_from_response(req, &response) >= 0) { + http_client_request_redirect + (req, response.status, response.location); + handled = TRUE; + } + /* service unavailable */ + } else if (response.status == 503) { + /* automatically retry after delay if indicated */ + if ( response.retry_after != (time_t)-1 && + http_client_request_delay_from_response(req, &response) > 0 && + http_client_request_try_retry(req)) + handled = TRUE; } - /* service unavailable */ - } else if (response.status == 503) { - /* automatically retry after delay if indicated */ - if ( response.retry_after != (time_t)-1 && - http_client_request_delay_from_response(req, &response) > 0 && - http_client_request_try_retry(req)) - handled = TRUE; } if (!handled) {
--- a/src/lib-http/http-client-request.c Sun Dec 08 23:26:40 2013 +0200 +++ b/src/lib-http/http-client-request.c Sun Dec 08 23:41:33 2013 +0200 @@ -622,21 +622,23 @@ if (!req->have_hdr_expect && req->payload_sync) { str_append(rtext, "Expect: 100-continue\r\n"); } - if (req->payload_chunked) { - // FIXME: can't do this for a HTTP/1.0 server - if (!req->have_hdr_body_spec) - str_append(rtext, "Transfer-Encoding: chunked\r\n"); - req->payload_output = - http_transfer_chunked_ostream_create(output); - } else if (req->payload_input != NULL) { - /* send Content-Length if we have specified a payload, - even if it's 0 bytes. */ - if (!req->have_hdr_body_spec) { - str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n", - req->payload_size); + if (req->payload_input != NULL) { + if (req->payload_chunked) { + // FIXME: can't do this for a HTTP/1.0 server + if (!req->have_hdr_body_spec) + str_append(rtext, "Transfer-Encoding: chunked\r\n"); + req->payload_output = + http_transfer_chunked_ostream_create(output); + } else { + /* send Content-Length if we have specified a payload, + even if it's 0 bytes. */ + if (!req->have_hdr_body_spec) { + str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n", + req->payload_size); + } + req->payload_output = output; + o_stream_ref(output); } - req->payload_output = output; - o_stream_ref(output); } if (!req->have_hdr_connection && req->host_url == &req->origin_url) { /* https://tools.ietf.org/html/rfc2068 @@ -814,6 +816,8 @@ struct http_url *url; const char *error, *target, *origin_url; + i_assert(!req->payload_wait); + /* parse URL */ if (http_url_parse(location, NULL, 0, pool_datastack_create(), &url, &error) < 0) { @@ -901,6 +905,8 @@ void http_client_request_resubmit(struct http_client_request *req) { + i_assert(!req->payload_wait); + http_client_request_debug(req, "Resubmitting request"); /* rewind payload stream */