]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: client: Perform output stream error handling in one place.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sat, 17 Feb 2018 10:32:37 +0000 (11:32 +0100)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Mon, 12 Mar 2018 08:42:26 +0000 (10:42 +0200)
src/lib-http/http-client-connection.c
src/lib-http/http-client-private.h
src/lib-http/http-client-request.c

index 13e3ff710848844b35004a9fb4623331a7026eb9..81e07c2592a42b27eeb3d1864bbb63044d846f25 100644 (file)
@@ -577,7 +577,6 @@ http_client_connection_continue_timeout(struct http_client_connection *conn)
        struct http_client_request *const *wait_reqs;
        struct http_client_request *req;
        unsigned int wait_count;
-       const char *error;
 
        i_assert(conn->pending_request == NULL);
 
@@ -592,10 +591,7 @@ http_client_connection_continue_timeout(struct http_client_connection *conn)
        req = wait_reqs[wait_count-1];
 
        req->payload_sync_continue = TRUE;
-       if (http_client_request_send_more(req, FALSE, &error) < 0) {
-               http_client_connection_lost(&conn,
-                       t_strdup_printf("Failed to send request: %s", error));
-       }
+       (void)http_client_request_send_more(req, FALSE);
 }
 
 int http_client_connection_next_request(struct http_client_connection *conn)
@@ -603,7 +599,6 @@ int http_client_connection_next_request(struct http_client_connection *conn)
        struct http_client_peer *peer = conn->peer;
        struct http_client_peer_shared *pshared = conn->ppool->peer;
        struct http_client_request *req = NULL;
-       const char *error;
        bool pipelined;
        int ret;
 
@@ -636,11 +631,8 @@ int http_client_connection_next_request(struct http_client_connection *conn)
        e_debug(conn->event, "Claimed request %s",
                http_client_request_label(req));
 
-       if (http_client_request_send(req, pipelined, &error) < 0) {
-               http_client_connection_lost(&conn,
-                       t_strdup_printf("Failed to send request: %s", error));
+       if (http_client_request_send(req, pipelined) < 0)
                return -1;
-       }
 
        if (req->connect_tunnel)
                conn->tunneling = TRUE;
@@ -1028,10 +1020,7 @@ static void http_client_connection_input(struct connection *_conn)
                                return;
                        }
 
-                       if (http_client_request_send_more(req, FALSE, &error) < 0) {
-                               http_client_connection_lost(&conn,
-                                       t_strdup_printf("Failed to send request: %s", error));
-                       }
+                       (void)http_client_request_send_more(req, FALSE);
                        return;
                } else if (response.status / 100 == 1) {
                        /* ignore other 1xx for now */
@@ -1201,7 +1190,6 @@ int http_client_connection_output(struct http_client_connection *conn)
        struct http_client_request *const *reqs;
        struct ostream *output = conn->conn.output;
        unsigned int count;
-       const char *error;
        int ret;
 
        /* we've seen activity from the server; reset request timeout */
@@ -1237,10 +1225,8 @@ int http_client_connection_output(struct http_client_connection *conn)
                }
 
                if (!req->payload_sync || req->payload_sync_continue) {
-                       if (http_client_request_send_more(req, pipelined, &error) < 0) {
-                               http_client_connection_lost(&conn, error);
+                       if (http_client_request_send_more(req, pipelined) < 0)
                                return -1;
-                       }
                        if (!conn->output_locked) {
                                /* room for new requests */
                                if (http_client_connection_check_ready(conn) > 0)
index b89d8f13f208162d3f81c0f7a9380ed424ee4896..cd218c0ccc508ead77dd88c21cc1304ec5422fb4 100644 (file)
@@ -484,9 +484,9 @@ void http_client_request_get_peer_addr(const struct http_client_request *req,
 enum http_response_payload_type
 http_client_request_get_payload_type(struct http_client_request *req);
 int http_client_request_send(struct http_client_request *req,
-                           bool pipelined, const char **error_r);
+                           bool pipelined);
 int http_client_request_send_more(struct http_client_request *req,
-                                 bool pipelined, const char **error_r);
+                                 bool pipelined);
 bool http_client_request_callback(struct http_client_request *req,
        struct http_response *response);
 void http_client_request_connect_callback(struct http_client_request *req,
index 3510f87a43e3fd39876d2db11afe510a53cbeb1c..d6b3d6c21efa03b719bf9abac94e635ffca33d70 100644 (file)
@@ -1054,12 +1054,13 @@ static void http_client_request_payload_input(struct http_client_request *req)
 }
 
 int http_client_request_send_more(struct http_client_request *req,
-                                 bool pipelined, const char **error_r)
+                                 bool pipelined)
 {
        struct http_client_connection *conn = req->conn;
        struct http_client_context *cctx = conn->ppool->peer->cctx;
        struct ostream *output = req->payload_output;
        enum ostream_send_istream_result res;
+       const char *error;
        uoff_t offset;
 
        i_assert(req->payload_input != NULL);
@@ -1083,11 +1084,12 @@ int http_client_request_send_more(struct http_client_request *req,
                /* finished sending */
                if (!req->payload_chunked &&
                    req->payload_input->v_offset - req->payload_offset != req->payload_size) {
-                       *error_r = t_strdup_printf("BUG: stream '%s' input size changed: "
+                       error = t_strdup_printf("BUG: stream '%s' input size changed: "
                                "%"PRIuUOFF_T"-%"PRIuUOFF_T" != %"PRIuUOFF_T,
                                i_stream_get_name(req->payload_input),
                                req->payload_input->v_offset, req->payload_offset, req->payload_size);
-                       i_error("%s", *error_r); //FIXME: remove?
+                       i_error("%s", error); //FIXME: remove?
+                       http_client_connection_lost(&conn, error);
                        return -1;
                }
 
@@ -1123,28 +1125,28 @@ int http_client_request_send_more(struct http_client_request *req,
        case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
                /* we're in the middle of sending a request, so the connection
                   will also have to be aborted */
-               *error_r = t_strdup_printf("read(%s) failed: %s",
-                                          i_stream_get_name(req->payload_input),
-                                          i_stream_get_error(req->payload_input));
+               error = t_strdup_printf("read(%s) failed: %s",
+                                       i_stream_get_name(req->payload_input),
+                                       i_stream_get_error(req->payload_input));
 
                /* the payload stream assigned to this request is broken,
                   fail this the request immediately */
                http_client_request_error(&req,
                        HTTP_CLIENT_REQUEST_ERROR_BROKEN_PAYLOAD,
                        "Broken payload stream");
+
+               http_client_connection_lost(&conn, error);
                return -1;
        case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
                /* failed to send request */
-               *error_r = t_strdup_printf("write(%s) failed: %s",
-                                          o_stream_get_name(output),
-                                          o_stream_get_error(output));
+               http_client_connection_handle_output_error(conn);
                return -1;
        }
        i_unreached();
 }
 
 static int http_client_request_send_real(struct http_client_request *req,
-                                        bool pipelined, const char **error_r)
+                                        bool pipelined)
 {
        const struct http_client_settings *set = &req->client->set;
        struct http_client_connection *conn = req->conn;
@@ -1263,17 +1265,14 @@ static int http_client_request_send_real(struct http_client_request *req,
                io_wait_timer_get_usecs(req->conn->io_wait_timer);
        o_stream_cork(output);
        if (o_stream_sendv(output, iov, N_ELEMENTS(iov)) < 0) {
-               *error_r = t_strdup_printf("write(%s) failed: %s",
-                                          o_stream_get_name(output),
-                                          o_stream_get_error(output));
+               http_client_connection_handle_output_error(conn);
                ret = -1;
        } else {
                e_debug(req->event, "Sent header");
 
                if (req->payload_output != NULL) {
                        if (!req->payload_sync) {
-                               if (http_client_request_send_more
-                                       (req, pipelined, error_r) < 0)
+                               if (http_client_request_send_more(req, pipelined) < 0)
                                        ret = -1;
                        } else {
                                e_debug(req->event, "Waiting for 100-continue");
@@ -1287,9 +1286,7 @@ static int http_client_request_send_real(struct http_client_request *req,
                }
        }
        if (ret >= 0 && o_stream_uncork_flush(output) < 0) {
-               *error_r = t_strdup_printf("flush(%s) failed: %s",
-                                          o_stream_get_name(output),
-                                          o_stream_get_error(output));
+               http_client_connection_handle_output_error(conn);
                ret = -1;
        }
 
@@ -1297,18 +1294,14 @@ static int http_client_request_send_real(struct http_client_request *req,
 }
 
 int http_client_request_send(struct http_client_request *req,
-                            bool pipelined, const char **error_r)
+                            bool pipelined)
 {
-       char *errstr = NULL;
        int ret;
 
        T_BEGIN {
-               ret = http_client_request_send_real(req, pipelined, error_r);
-               if (ret < 0)
-                       errstr = i_strdup(*error_r);
+               ret = http_client_request_send_real(req, pipelined);
        } T_END;
-       *error_r = t_strdup(errstr);
-       i_free(errstr);
+
        return ret;
 }