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_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_deinit(struct http_client **_client) { struct http_client *client = *_client; struct http_client_request *req; struct http_client_host *host; struct http_client_peer *peer; *_client = NULL; /* destroy requests without calling callbacks */ req = client->requests_list; while (req != NULL) { struct http_client_request *next_req = req->next; http_client_request_destroy(&req); req = next_req; } i_assert(client->requests_count == 0); /* free peers */ while (client->peers_list != NULL) { peer = client->peers_list; http_client_peer_close(&peer); } hash_table_destroy(&client->peers); /* free hosts */ while (client->hosts_list != NULL) { host = client->hosts_list; http_client_host_free(&host); } hash_table_destroy(&client->hosts); array_free(&client->delayed_failing_requests); if (client->to_failing_requests != NULL) timeout_remove(&client->to_failing_requests); connection_list_deinit(&client->conn_list); if (client->ssl_ctx != NULL) ssl_iostream_context_deinit(&client->ssl_ctx); pool_unref(&client->pool); }
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); }