void http_client_request_error(struct http_client_request **_req, unsigned int status, const char *error) { struct http_client_request *req = *_req; i_assert(req->state < HTTP_REQUEST_STATE_FINISHED); req->state = HTTP_REQUEST_STATE_ABORTED; if (req->queue != NULL) http_client_queue_drop_request(req->queue, req); if (!req->submitted || req->state == HTTP_REQUEST_STATE_GOT_RESPONSE) { /* we're still in http_client_request_submit() or in the callback during a retry attempt. delay reporting the error, so the caller doesn't have to handle immediate or nested callbacks. */ i_assert(req->delayed_error == NULL); req->delayed_error = p_strdup(req->pool, error); req->delayed_error_status = status; http_client_delay_request_error(req->client, req); } else { if (http_client_request_send_error(req, status, error)) http_client_request_destroy(&req); } *_req = NULL; }
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); if (req->state < HTTP_REQUEST_STATE_FINISHED) req->state = HTTP_REQUEST_STATE_ABORTED; req->callback = NULL; if (req->queue != NULL) http_client_queue_drop_request(req->queue, req); if (req->destroy_callback != NULL) { void (*callback)(void *) = req->destroy_callback; req->destroy_callback = NULL; callback(req->destroy_context); } http_client_request_remove(req); http_client_request_unref(&req); }
void http_client_request_abort(struct http_client_request **_req) { struct http_client_request *req = *_req; if (req->state >= HTTP_REQUEST_STATE_FINISHED) return; req->callback = NULL; req->state = HTTP_REQUEST_STATE_ABORTED; if (req->queue != NULL) http_client_queue_drop_request(req->queue, req); http_client_request_unref(_req); }
void http_client_request_error_delayed(struct http_client_request **_req) { struct http_client_request *req = *_req; 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); }
void http_client_request_finish(struct http_client_request *req) { if (req->state >= HTTP_REQUEST_STATE_FINISHED) return; i_assert(req->refcount > 0); http_client_request_debug(req, "Finished"); req->callback = NULL; req->state = HTTP_REQUEST_STATE_FINISHED; if (req->queue != 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); }
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 TRUE; http_client_request_debug(req, "Free (requests left=%d)", client->requests_count); /* cannot be destroyed while it is still pending */ i_assert(req->conn == NULL); if (req->queue != NULL) http_client_queue_drop_request(req->queue, req); if (req->destroy_callback != NULL) { req->destroy_callback(req->destroy_context); req->destroy_callback = NULL; } http_client_request_remove(req); if (client->requests_count == 0 && client->ioloop != NULL) io_loop_stop(client->ioloop); if (req->delayed_error != NULL) http_client_remove_request_error(req->client, req); if (req->payload_input != NULL) i_stream_unref(&req->payload_input); if (req->payload_output != NULL) o_stream_unref(&req->payload_output); if (req->headers != NULL) str_free(&req->headers); pool_unref(&req->pool); return FALSE; }
void http_client_request_abort(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; req->callback = NULL; req->state = HTTP_REQUEST_STATE_ABORTED; /* release payload early (prevents server/client deadlock in proxy) */ if (!sending && req->payload_input != NULL) i_stream_unref(&req->payload_input); if (req->queue != 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_destroy(&req); }