static bool http_client_request_send_error(struct http_client_request *req, unsigned int status, const char *error) { http_client_request_callback_t *callback; bool sending = (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT); unsigned int orig_attempts = req->attempts; req->state = HTTP_REQUEST_STATE_ABORTED; callback = req->callback; req->callback = NULL; if (callback != NULL) { struct http_response response; http_response_init(&response, status, error); (void)callback(&response, req->context); if (req->attempts != orig_attempts) { /* retrying */ req->callback = callback; http_client_request_resubmit(req); return FALSE; } else { /* release payload early (prevents server/client deadlock in proxy) */ if (!sending && req->payload_input != NULL) i_stream_unref(&req->payload_input); } } if (req->payload_wait && req->client->ioloop != NULL) io_loop_stop(req->client->ioloop); return TRUE; }
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) { struct http_response response_copy = *response; if (req->attempts > 0 && !req->preserve_exact_reason) { unsigned int total_msecs = timeval_diff_msecs(&ioloop_timeval, &req->submit_time); response_copy.reason = t_strdup_printf( "%s (%u attempts in %u.%03u secs)", response_copy.reason, req->attempts, total_msecs/1000, total_msecs%1000); } callback(&response_copy, req->context); if (req->attempts != orig_attempts) { /* retrying */ req->callback = callback; http_client_request_resubmit(req); return FALSE; } else { /* release payload early (prevents server/client deadlock in proxy) */ if (req->payload_input != NULL) i_stream_unref(&req->payload_input); } } return TRUE; }
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++; http_client_request_debug(req, "Retrying (attempts=%d)", req->attempts); if (req->callback != NULL) http_client_request_resubmit(req); return TRUE; }
bool http_client_request_try_retry(struct http_client_request *req) { /* don't ever retry if we're sending data in small blocks via http_client_request_send_payload() and we're not waiting for a 100 continue (there's no way to rewind the payload for a retry) */ if (req->payload_wait && (!req->payload_sync || req->payload_sync_continue)) return FALSE; /* limit the number of attempts for each request */ if (req->attempts+1 >= req->client->set.max_attempts) return FALSE; req->attempts++; http_client_request_debug(req, "Retrying (attempts=%d)", req->attempts); if (req->callback != NULL) http_client_request_resubmit(req); return TRUE; }
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) { callback(response, req->context); if (req->attempts != orig_attempts) { /* retrying */ req->callback = callback; http_client_request_resubmit(req); return FALSE; } else { /* release payload early (prevents server/client deadlock in proxy) */ if (req->payload_input != NULL) i_stream_unref(&req->payload_input); } } return TRUE; }