From: Stephan Bosch Date: Mon, 19 Feb 2018 12:27:39 +0000 (+0100) Subject: lib-http: client: Add event fields for the number of bytes sent and received for... X-Git-Tag: 2.3.1~91 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f904b00fb68f6b0ffd2d565b3825bf692a57a1dc;p=thirdparty%2Fdovecot%2Fcore.git lib-http: client: Add event fields for the number of bytes sent and received for each request in the last attempt. --- diff --git a/src/lib-http/http-client-connection.c b/src/lib-http/http-client-connection.c index 99df9fe801..00a23db934 100644 --- a/src/lib-http/http-client-connection.c +++ b/src/lib-http/http-client-connection.c @@ -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); diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index da822d667e..8d3544e971 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -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; diff --git a/src/lib-http/http-client-request.c b/src/lib-http/http-client-request.c index 5fb6cd72af..1f271e1cde 100644 --- a/src/lib-http/http-client-request.c +++ b/src/lib-http/http-client-request.c @@ -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; }