]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: client: Add event fields for the number of bytes sent and received for...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 19 Feb 2018 12:27:39 +0000 (13:27 +0100)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Mon, 12 Mar 2018 09:07:37 +0000 (11:07 +0200)
src/lib-http/http-client-connection.c
src/lib-http/http-client-private.h
src/lib-http/http-client-request.c

index 99df9fe8015d137db71494203bb8d926b3dc3724..00a23db934fda610969a56f943e8fc651a69c337 100644 (file)
@@ -739,6 +739,9 @@ static void http_client_payload_destroyed(struct http_client_request *req)
           the payload. make sure here that it's switched back. */
        net_set_nonblock(conn->conn.fd_in, TRUE);
 
+       i_assert(req->response_offset < conn->conn.input->v_offset);
+       req->bytes_in = conn->conn.input->v_offset - req->response_offset;
+
        /* drop reference from connection */
        if (http_client_connection_unref_request(conn, &conn->pending_request)) {
                /* finish request if not already aborted */
@@ -992,7 +995,13 @@ static void http_client_connection_input(struct connection *_conn)
                        http_client_connection_close(&conn);
                        return;
                }
+
                req->response_time = ioloop_timeval;
+               req->response_offset =
+                       http_response_parser_get_last_offset(conn->http_parser);
+               i_assert(req->response_offset != (uoff_t)-1);
+               i_assert(req->response_offset < conn->conn.input->v_offset);
+               req->bytes_in = conn->conn.input->v_offset - req->response_offset;
 
                /* Got some response; cancel response timeout */
                timeout_remove(&conn->to_response);
index da822d667eb183a6aaadeaf5c54ba4cceac16ca4..8d3544e971f1d171d04d2347ee11a773f7974915 100644 (file)
@@ -118,6 +118,9 @@ struct http_client_request {
        unsigned int attempt_timeout_msecs;
        unsigned int max_attempts;
 
+       uoff_t response_offset, request_offset;
+       uoff_t bytes_in, bytes_out;
+
        unsigned int attempts;
        unsigned int redirects;
        uint64_t sent_global_ioloop_usecs;
index 5fb6cd72afa763d6d25a1c174e5a15aee9c4094b..1f271e1cde80601a3ed2aae2e36380c77ec62e9c 100644 (file)
@@ -64,10 +64,35 @@ http_client_request_update_event(struct http_client_request *req)
 static struct event_passthrough *
 http_client_request_result_event(struct http_client_request *req)
 {
+       struct http_client_connection *conn = req->conn;
+
+       if (conn != NULL) {
+               if (req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT) {
+                       /* got here prematurely; use bytes written so far */
+                       i_assert(req->request_offset <
+                                conn->conn.output->offset);
+                       req->bytes_out = conn->conn.output->offset -
+                               req->request_offset;
+               }
+               if (conn->incoming_payload != NULL &&
+                       (req->state == HTTP_REQUEST_STATE_GOT_RESPONSE ||
+                        req->state == HTTP_REQUEST_STATE_PAYLOAD_IN)) {
+                       /* got here prematurely; use bytes read so far */
+                       i_assert(conn->in_req_callback ||
+                                conn->pending_request == req);
+                       i_assert(req->response_offset <
+                                conn->conn.input->v_offset);
+                       req->bytes_in = conn->conn.input->v_offset -
+                               req->response_offset;
+               }
+       }
+
        return event_create_passthrough(req->event)->
                add_int("status_code", req->last_status)->
                add_int("attempts", req->attempts)->
-               add_int("redirects", req->redirects);
+               add_int("redirects", req->redirects)->
+               add_int("bytes_in", req->bytes_in)->
+               add_int("bytes_out", req->bytes_out);
 }
 
 static struct http_client_request *
@@ -884,7 +909,9 @@ http_client_request_get_peer_addr(const struct http_client_request *req,
 static void
 http_client_request_finish_payload_out(struct http_client_request *req)
 {
-       i_assert(req->conn != NULL);
+       struct http_client_connection *conn = req->conn;
+
+       i_assert(conn != NULL);
 
        /* drop payload output stream */
        if (req->payload_output != NULL) {
@@ -892,17 +919,20 @@ http_client_request_finish_payload_out(struct http_client_request *req)
                req->payload_output = NULL;
        }
 
+       i_assert(req->request_offset < conn->conn.output->offset);
+       req->bytes_out = conn->conn.output->offset - req->request_offset;
+
        /* advance state only when request didn't get aborted in the mean time */
        if (req->state != HTTP_REQUEST_STATE_ABORTED) {
                i_assert(req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT);
 
                /* we're now waiting for a response from the server */
                req->state = HTTP_REQUEST_STATE_WAITING;
-               http_client_connection_start_request_timeout(req->conn);
+               http_client_connection_start_request_timeout(conn);
        }
 
        /* release connection */
-       req->conn->output_locked = FALSE;
+       conn->output_locked = FALSE;
 
        e_debug(req->event, "Finished sending%s payload",
                (req->state == HTTP_REQUEST_STATE_ABORTED ? " aborted" : ""));
@@ -1273,6 +1303,7 @@ static int http_client_request_send_real(struct http_client_request *req,
        req->sent_http_ioloop_usecs =
                io_wait_timer_get_usecs(req->conn->io_wait_timer);
        o_stream_cork(conn->conn.output);
+       req->request_offset = conn->conn.output->offset;
        if (o_stream_sendv(conn->conn.output, iov, N_ELEMENTS(iov)) < 0) {
                http_client_connection_handle_output_error(conn);
                return -1;
@@ -1294,10 +1325,13 @@ static int http_client_request_send_real(struct http_client_request *req,
                        http_client_connection_start_request_timeout(req->conn);
                conn->output_locked = FALSE;
        }
-       if (conn->conn.output != NULL &&
-           o_stream_uncork_flush(conn->conn.output) < 0) {
-               http_client_connection_handle_output_error(conn);
-               return -1;
+       if (conn->conn.output != NULL) {
+               i_assert(req->request_offset < conn->conn.output->offset);
+               req->bytes_out = conn->conn.output->offset - req->request_offset;
+               if (o_stream_uncork_flush(conn->conn.output) < 0) {
+                       http_client_connection_handle_output_error(conn);
+                       return -1;
+               }
        }
        return 0;
 }