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..
/* 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;
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,
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
void http_client_request_retry(struct http_client_request *req,
unsigned int status, const char *error)
{
- /* limit the number of attempts for each request */
- if (++req->attempts >= req->client->set.max_attempts) {
- /* return error */
+ if (!http_client_request_try_retry(req))
http_client_request_error(req, status, error);
- return;
- }
+}
- http_client_request_debug(req, "Retrying (attempts=%d)", req->attempts);
+bool http_client_request_try_retry(struct http_client_request *req)
+{
+ /* limit the number of attempts for each request */
+ if (req->attempts+1 >= req->client->set.max_attempts)
+ return FALSE;
+ req->attempts++;
- /* resubmit */
- http_client_request_resubmit(req);
+ http_client_request_debug(req, "Retrying (attempts=%d)", req->attempts);
+ if (req->callback != NULL)
+ http_client_request_resubmit(req);
+ return TRUE;
}
void http_client_request_set_destroy_callback(struct http_client_request *req,
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. */