dovecot-2.2: lib-http: http-client: Added request error code for...

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 12 11:14:58 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/a8fe88d2286d
changeset: 16852:a8fe88d2286d
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sat Oct 12 10:57:05 2013 +0300
description:
lib-http: http-client: Added request error code for broken payload input stream.
This error is triggered when reading from the provided payload input stream
fails while sending the request. Previously this would yield the same error
code as for a failure to write to the connection output.

diffstat:

 src/lib-http/http-client-connection.c |   6 ++++--
 src/lib-http/http-client-private.h    |   4 +++-
 src/lib-http/http-client-request.c    |  16 ++++++++++++++--
 src/lib-http/http-client.h            |   1 +
 4 files changed, 22 insertions(+), 5 deletions(-)

diffs (112 lines):

diff -r b4d54b6f3d10 -r a8fe88d2286d src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c	Sat Oct 12 10:55:38 2013 +0300
+++ b/src/lib-http/http-client-connection.c	Sat Oct 12 10:57:05 2013 +0300
@@ -74,7 +74,8 @@
 	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);
@@ -93,7 +94,8 @@
 		"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);
diff -r b4d54b6f3d10 -r a8fe88d2286d src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h	Sat Oct 12 10:55:38 2013 +0300
+++ b/src/lib-http/http-client-private.h	Sat Oct 12 10:57:05 2013 +0300
@@ -232,7 +232,7 @@
 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,
@@ -242,6 +242,8 @@
 	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,
diff -r b4d54b6f3d10 -r a8fe88d2286d src/lib-http/http-client-request.c
--- a/src/lib-http/http-client-request.c	Sat Oct 12 10:55:38 2013 +0300
+++ b/src/lib-http/http-client-request.c	Sat Oct 12 10:57:05 2013 +0300
@@ -377,11 +377,20 @@
 	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));
@@ -393,6 +402,7 @@
 	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;
 		}
@@ -552,12 +562,14 @@
 	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;
@@ -603,7 +615,7 @@
 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. */
diff -r b4d54b6f3d10 -r a8fe88d2286d src/lib-http/http-client.h
--- a/src/lib-http/http-client.h	Sat Oct 12 10:55:38 2013 +0300
+++ b/src/lib-http/http-client.h	Sat Oct 12 10:57:05 2013 +0300
@@ -16,6 +16,7 @@
 	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,
 };


More information about the dovecot-cvs mailing list