conn->incoming_payload = NULL;
conn->pending_request = NULL;
http_client_connection_ref(conn);
- http_client_request_finish(&req);
+ http_client_request_finish(req);
/* room for new requests */
if (http_client_connection_is_ready(conn))
conn->to_input =
timeout_add_short(0, http_client_payload_destroyed_timeout, conn);
- i_assert(req != NULL);
http_client_request_unref(&req);
http_client_connection_unref(&conn);
}
if (!http_client_connection_unref(&req->conn)) {
/* the callback managed to get this connection destroyed */
if (!retrying)
- http_client_request_finish(&req);
+ http_client_request_finish(req);
http_client_request_unref(&req);
return FALSE;
}
}
} else {
req->conn = NULL;
- http_client_request_finish(&req);
+ http_client_request_finish(req);
http_client_request_unref(&req);
}
(struct http_client_connection *)_conn;
struct http_response response;
struct http_client_request *const *reqs;
- struct http_client_request *req = NULL;
+ struct http_client_request *req = NULL, *req_ref;
enum http_response_payload_type payload_type;
unsigned int count;
int finished = 0, ret;
/* 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);
+ req_ref = req;
+ if (!http_client_request_unref(&req_ref)) {
+ i_assert(aborted);
+ req = NULL;
+ }
conn->close_indicated = response.connection_close;
int http_client_init_ssl_ctx(struct http_client *client, const char **error_r);
void http_client_request_ref(struct http_client_request *req);
-void http_client_request_unref(struct http_client_request **_req);
+/* Returns FALSE if unrefing destroyed the request entirely */
+bool http_client_request_unref(struct http_client_request **_req);
void http_client_request_destroy(struct http_client_request **_req);
int http_client_request_delay_from_response(struct http_client_request *req,
unsigned int status, const char *error);
void http_client_request_redirect(struct http_client_request *req,
unsigned int status, const char *location);
-void http_client_request_finish(struct http_client_request **_req);
+void http_client_request_finish(struct http_client_request *req);
struct connection_list *http_client_connection_list_init(void);
req->refcount++;
}
-void http_client_request_unref(struct http_client_request **_req)
+bool http_client_request_unref(struct http_client_request **_req)
{
struct http_client_request *req = *_req;
struct http_client *client = req->client;
i_assert(req->refcount > 0);
+ *_req = NULL;
+
if (--req->refcount > 0)
- return;
+ return TRUE;
http_client_request_debug(req, "Free (requests left=%d)",
client->requests_count);
if (req->headers != NULL)
str_free(&req->headers);
pool_unref(&req->pool);
- *_req = NULL;
+ return FALSE;
}
void http_client_request_destroy(struct http_client_request **_req)
struct http_client_request *req = *_req;
struct http_client *client = req->client;
+ *_req = NULL;
+
http_client_request_debug(req, "Destroy (requests left=%d)",
client->requests_count);
req->destroy_callback = NULL;
callback(req->destroy_context);
}
-
- http_client_request_unref(_req);
+ http_client_request_unref(&req);
}
void http_client_request_set_port(struct http_client_request *req,
/* callback may have messed with our pointer,
so unref using local variable */
- http_client_request_unref(&req);
- if (req == NULL)
+ if (!http_client_request_unref(&req))
*_req = NULL;
if (conn != NULL)
i_assert(req->state == HTTP_REQUEST_STATE_ABORTED);
+ *_req = NULL;
+
i_assert(req->delayed_error != NULL && req->delayed_error_status != 0);
http_client_request_send_error(req, req->delayed_error_status,
req->delayed_error);
if (req->queue != NULL)
http_client_queue_drop_request(req->queue, req);
- http_client_request_destroy(_req);
+ http_client_request_destroy(&req);
}
void http_client_request_error(struct http_client_request *req,
struct http_client_request *req = *_req;
bool sending = (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT);
+ *_req = NULL;
+
if (req->state >= HTTP_REQUEST_STATE_FINISHED)
return;
http_client_queue_drop_request(req->queue, req);
if (req->payload_wait && req->client->ioloop != NULL)
io_loop_stop(req->client->ioloop);
- http_client_request_destroy(_req);
+ http_client_request_destroy(&req);
}
-void http_client_request_finish(struct http_client_request **_req)
+void http_client_request_finish(struct http_client_request *req)
{
- struct http_client_request *req = *_req;
-
if (req->state >= HTTP_REQUEST_STATE_FINISHED)
return;
+ i_assert(req->refcount > 1);
http_client_request_debug(req, "Finished");
req->callback = NULL;
http_client_queue_drop_request(req->queue, req);
if (req->payload_wait && req->client->ioloop != NULL)
io_loop_stop(req->client->ioloop);
- http_client_request_unref(_req);
+ http_client_request_unref(&req);
}
void http_client_request_redirect(struct http_client_request *req,