dovecot-2.2: lib-http: Callback can now request a retry with htt...

dovecot at dovecot.org dovecot at dovecot.org
Sun Mar 10 20:38:40 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/59572bce44fe
changeset: 16013:59572bce44fe
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Mar 10 20:37:41 2013 +0200
description:
lib-http: Callback can now request a retry with http_client_request_try_retry()
This can be useful for handling "try again" errors from HTTP servers.

diffstat:

 src/lib-http/http-client-connection.c |  13 ++++++++++++-
 src/lib-http/http-client-private.h    |   2 +-
 src/lib-http/http-client-request.c    |  33 +++++++++++++++++++++++----------
 src/lib-http/http-client.h            |   1 +
 4 files changed, 37 insertions(+), 12 deletions(-)

diffs (114 lines):

diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c	Sun Mar 10 20:34:49 2013 +0200
+++ b/src/lib-http/http-client-connection.c	Sun Mar 10 20:37:41 2013 +0200
@@ -392,7 +392,17 @@
 		io_remove(&conn->conn.io);
 	}
 
-	http_client_request_callback(req, response);
+	if (!http_client_request_callback(req, response)) {
+		/* retrying, don't destroy the request */
+		if (response->payload != NULL) {
+			i_stream_unset_destroy_callback(conn->incoming_payload);
+			i_stream_unref(&conn->incoming_payload);
+			conn->conn.io = io_add(conn->conn.fd_in, IO_READ,
+					       http_client_connection_input,
+					       &conn->conn);
+		}
+		return TRUE;
+	}
 
 	// FIXME: conn may be freed at this point..
 
@@ -506,6 +516,7 @@
 		/* remove request from queue */
 		array_delete(&conn->request_wait_list, 0, 1);
 		aborted = (req->state == HTTP_REQUEST_STATE_ABORTED);
+		i_assert(req->refcount > 1 || aborted);
 		http_client_request_unref(&req);
 		
 		conn->close_indicated = response->connection_close;
diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h	Sun Mar 10 20:34:49 2013 +0200
+++ b/src/lib-http/http-client-private.h	Sun Mar 10 20:37:41 2013 +0200
@@ -191,7 +191,7 @@
 			     const char **error_r);
 int http_client_request_send_more(struct http_client_request *req,
 				  const char **error_r);
-void http_client_request_callback(struct http_client_request *req,
+bool http_client_request_callback(struct http_client_request *req,
 	struct http_response *response);
 void http_client_request_resubmit(struct http_client_request *req);
 void http_client_request_retry(struct http_client_request *req,
diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client-request.c
--- a/src/lib-http/http-client-request.c	Sun Mar 10 20:34:49 2013 +0200
+++ b/src/lib-http/http-client-request.c	Sun Mar 10 20:37:41 2013 +0200
@@ -412,16 +412,25 @@
 	return ret;
 }
 
-void http_client_request_callback(struct http_client_request *req,
+bool http_client_request_callback(struct http_client_request *req,
 			     struct http_response *response)
 {
 	http_client_request_callback_t *callback = req->callback;
+	unsigned int orig_attempts = req->attempts;
 
 	req->state = HTTP_REQUEST_STATE_GOT_RESPONSE;
 
 	req->callback = NULL;
-	if (callback != NULL)
+	if (callback != NULL) {
 		callback(response, req->context);
+		if (req->attempts != orig_attempts) {
+			/* retrying */
+			req->callback = callback;
+			http_client_request_resubmit(req);
+			return FALSE;
+		}
+	}
+	return TRUE;
 }
 
 static void
@@ -636,17 +645,21 @@
 void http_client_request_retry(struct http_client_request *req,
 	unsigned int status, const char *error)
 {
+	if (!http_client_request_try_retry(req))
+		http_client_request_error(req, status, error);
+}
+
+bool http_client_request_try_retry(struct http_client_request *req)
+{
 	/* limit the number of attempts for each request */
-	if (++req->attempts >= req->client->set.max_attempts) {
-		/* return error */
-		http_client_request_error(req, status, error);
-		return;
-	}
+	if (req->attempts+1 >= req->client->set.max_attempts)
+		return FALSE;
+	req->attempts++;
 
 	http_client_request_debug(req, "Retrying (attempts=%d)", req->attempts);
-
-	/* resubmit */
-	http_client_request_resubmit(req);
+	if (req->callback != NULL)
+		http_client_request_resubmit(req);
+	return TRUE;
 }
 
 void http_client_request_set_destroy_callback(struct http_client_request *req,
diff -r 7db226db28df -r 59572bce44fe src/lib-http/http-client.h
--- a/src/lib-http/http-client.h	Sun Mar 10 20:34:49 2013 +0200
+++ b/src/lib-http/http-client.h	Sun Mar 10 20:37:41 2013 +0200
@@ -90,6 +90,7 @@
 enum http_request_state
 http_client_request_get_state(struct http_client_request *req);
 void http_client_request_submit(struct http_client_request *req);
+bool http_client_request_try_retry(struct http_client_request *req);
 void http_client_request_abort(struct http_client_request **req);
 
 /* Call the specified callback when HTTP request is destroyed. */


More information about the dovecot-cvs mailing list