struct http_client_request **req;
array_foreach_modifiable(&conn->request_wait_list, req) {
- http_client_request_retry(*req, status, error);
+ if ((*req)->state < HTTP_REQUEST_STATE_FINISHED)
+ http_client_request_retry(*req, status, error);
http_client_request_unref(req);
}
array_clear(&conn->request_wait_list);
"Server explicitly closed connection");
array_foreach_modifiable(&conn->request_wait_list, req) {
- http_client_request_resubmit(*req);
+ if ((*req)->state < HTTP_REQUEST_STATE_FINISHED)
+ http_client_request_resubmit(*req);
http_client_request_unref(req);
}
array_clear(&conn->request_wait_list);
void http_client_request_ref(struct http_client_request *req);
void http_client_request_unref(struct http_client_request **_req);
int http_client_request_send(struct http_client_request *req,
- const char **error_r);
+ const char **error_r);
int http_client_request_send_more(struct http_client_request *req,
const char **error_r);
bool http_client_request_callback(struct http_client_request *req,
unsigned int status, const char *error);
void http_client_request_retry_response(struct http_client_request *req,
struct http_response *response);
+void http_client_request_send_error(struct http_client_request *req,
+ unsigned int status, const char *error);
void http_client_request_error(struct http_client_request *req,
unsigned int status, const char *error);
void http_client_request_redirect(struct http_client_request *req,
o_stream_set_max_buffer_size(output, (size_t)-1);
if (req->payload_input->stream_errno != 0) {
+ /* the payload stream assigned to this request is broken,
+ fail this the request immediately */
+ http_client_request_send_error(req,
+ HTTP_CLIENT_REQUEST_ERROR_BROKEN_PAYLOAD,
+ "Broken payload stream");
+
+ /* we're in the middle of sending a request, so the connection
+ will also have to be aborted */
errno = req->payload_input->stream_errno;
*error_r = t_strdup_printf("read(%s) failed: %m",
i_stream_get_name(req->payload_input));
ret = -1;
} else if (output->stream_errno != 0) {
+ /* failed to send request */
errno = output->stream_errno;
*error_r = t_strdup_printf("write(%s) failed: %m",
o_stream_get_name(output));
if (ret < 0 || i_stream_is_eof(req->payload_input)) {
if (!req->payload_chunked &&
req->payload_input->v_offset - req->payload_offset != req->payload_size) {
+ *error_r = "stream input size changed [BUG]";
i_error("stream input size changed"); //FIXME
return -1;
}
return TRUE;
}
-static void
+void
http_client_request_send_error(struct http_client_request *req,
unsigned int status, const char *error)
{
http_client_request_callback_t *callback;
+ if (req->state >= HTTP_REQUEST_STATE_FINISHED)
+ return;
req->state = HTTP_REQUEST_STATE_ABORTED;
callback = req->callback;
void http_client_request_error(struct http_client_request *req,
unsigned int status, const char *error)
{
- if (!req->submitted) {
+ if (!req->submitted && req->state < HTTP_REQUEST_STATE_FINISHED) {
/* we're still in http_client_request_submit(). delay
reporting the error, so the caller doesn't have to handle
immediate callbacks. */
HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED,
HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
+ HTTP_CLIENT_REQUEST_ERROR_BROKEN_PAYLOAD,
HTTP_CLIENT_REQUEST_ERROR_BAD_RESPONSE,
HTTP_CLIENT_REQUEST_ERROR_TIMED_OUT,
};