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