dovecot-2.2: lib-http: Don't try to automatically retry requests...

dovecot at dovecot.org dovecot at dovecot.org
Sun Dec 8 23:41:44 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/353c3e3edc52
changeset: 17052:353c3e3edc52
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Dec 08 23:41:33 2013 +0200
description:
lib-http: Don't try to automatically retry requests whose payload was already lost.
Patch by Stephan Bosch.

diffstat:

 src/lib-http/http-client-connection.c |  54 +++++++++++++++++++---------------
 src/lib-http/http-client-request.c    |  34 ++++++++++++---------
 2 files changed, 50 insertions(+), 38 deletions(-)

diffs (124 lines):

diff -r 7acfc7b1b8f4 -r 353c3e3edc52 src/lib-http/http-client-connection.c
--- 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) {
diff -r 7acfc7b1b8f4 -r 353c3e3edc52 src/lib-http/http-client-request.c
--- 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 */


More information about the dovecot-cvs mailing list