From d079b656b4719739b2247dcd9d46e9bec793095a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 Feb 2023 17:11:34 +0100 Subject: Merging upstream version 1.38.0. Signed-off-by: Daniel Baumann --- web/server/web_client.c | 68 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 23 deletions(-) (limited to 'web/server/web_client.c') diff --git a/web/server/web_client.c b/web/server/web_client.c index b3c5ada7a..c14b86f3e 100644 --- a/web/server/web_client.c +++ b/web/server/web_client.c @@ -129,10 +129,10 @@ void web_client_request_done(struct web_client *w) { , mode , sent , size - , -((size > 0) ? ((size - sent) / (double) size * 100.0) : 0.0) - , dt_usec(&w->tv_ready, &w->tv_in) / 1000.0 - , dt_usec(&tv, &w->tv_ready) / 1000.0 - , dt_usec(&tv, &w->tv_in) / 1000.0 + , -((size > 0) ? ((double)(size - sent) / (double) size * 100.0) : 0.0) + , (double)dt_usec(&w->tv_ready, &w->tv_in) / 1000.0 + , (double)dt_usec(&tv, &w->tv_ready) / 1000.0 + , (double)dt_usec(&tv, &w->tv_in) / 1000.0 , w->response.code , strip_control_characters(w->last_url) ); @@ -302,7 +302,7 @@ int mysendfile(struct web_client *w, char *filename) { } } - // if the filename contains a .. refuse to serve it + // if the filename contains a double dot refuse to serve it if(strstr(filename, "..") != 0) { debug(D_WEB_CLIENT_ACCESS, "%llu: File '%s' is not acceptable.", w->id, filename); w->response.data->contenttype = CT_TEXT_HTML; @@ -831,9 +831,8 @@ static inline char *web_client_valid_method(struct web_client *w, char *s) { * @param s is the first address of the string. * @param ptr is the address of the separator. */ -static void web_client_set_path_query(struct web_client *w, char *s, char *ptr) { +static void web_client_set_path_query(struct web_client *w, const char *s, char *ptr) { w->url_path_length = (size_t)(ptr -s); - w->url_search_path = ptr; } @@ -1250,12 +1249,15 @@ static inline void web_client_send_http_header(struct web_client *w) { if(bytes > 0) w->stats_sent_bytes += bytes; - error("HTTP headers failed to be sent (I sent %zu bytes but the system sent %zd bytes). Closing web client." - , buffer_strlen(w->response.header_output) - , bytes); + if (bytes < 0) { - WEB_CLIENT_IS_DEAD(w); - return; + error("HTTP headers failed to be sent (I sent %zu bytes but the system sent %zd bytes). Closing web client." + , buffer_strlen(w->response.header_output) + , bytes); + + WEB_CLIENT_IS_DEAD(w); + return; + } } else w->stats_sent_bytes += bytes; @@ -1314,6 +1316,9 @@ static inline int web_client_switch_host(RRDHOST *host, struct web_client *w, ch } static inline int web_client_process_url(RRDHOST *host, struct web_client *w, char *url) { + if(unlikely(!service_running(ABILITY_WEB_REQUESTS))) + return web_client_permission_denied(w); + static uint32_t hash_api = 0, hash_netdata_conf = 0, @@ -1423,7 +1428,7 @@ static inline int web_client_process_url(RRDHOST *host, struct web_client *w, ch // replace the zero bytes with spaces buffer_char_replace(w->response.data, '\0', ' '); - // just leave the buffer as is + // just leave the buffer as-is // it will be copied back to the client return HTTP_RESP_OK; @@ -1540,7 +1545,7 @@ void web_client_process_request(struct web_client *w) { break; } - // keep track of the time we done processing + // keep track of the processing time now_realtime_timeval(&w->tv_ready); w->response.sent = 0; @@ -1612,7 +1617,6 @@ ssize_t web_client_send_chunk_header(struct web_client *w, size_t len) else if(bytes == 0) { debug(D_WEB_CLIENT, "%llu: Did not send chunk header to the client.", w->id); - WEB_CLIENT_IS_DEAD(w); } else { debug(D_WEB_CLIENT, "%llu: Failed to send chunk header to client.", w->id); @@ -1635,7 +1639,6 @@ ssize_t web_client_send_chunk_close(struct web_client *w) else if(bytes == 0) { debug(D_WEB_CLIENT, "%llu: Did not send chunk suffix to the client.", w->id); - WEB_CLIENT_IS_DEAD(w); } else { debug(D_WEB_CLIENT, "%llu: Failed to send chunk suffix to client.", w->id); @@ -1658,7 +1661,6 @@ ssize_t web_client_send_chunk_finalize(struct web_client *w) else if(bytes == 0) { debug(D_WEB_CLIENT, "%llu: Did not send chunk finalize suffix to the client.", w->id); - WEB_CLIENT_IS_DEAD(w); } else { debug(D_WEB_CLIENT, "%llu: Failed to send chunk finalize suffix to client.", w->id); @@ -1775,7 +1777,6 @@ ssize_t web_client_send_deflate(struct web_client *w) debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client (zhave = %zu, zsent = %zu, need to send = %zu).", w->id, w->response.zhave, w->response.zsent, w->response.zhave - w->response.zsent); - WEB_CLIENT_IS_DEAD(w); } else { debug(D_WEB_CLIENT, "%llu: Failed to send data to client.", w->id); @@ -1828,7 +1829,6 @@ ssize_t web_client_send(struct web_client *w) { } else if(likely(bytes == 0)) { debug(D_WEB_CLIENT, "%llu: Did not send any bytes to the client.", w->id); - WEB_CLIENT_IS_DEAD(w); } else { debug(D_WEB_CLIENT, "%llu: Failed to send data to client.", w->id); @@ -1846,7 +1846,7 @@ ssize_t web_client_read_file(struct web_client *w) if(unlikely(w->response.rlen <= w->response.data->len)) return 0; - ssize_t left = w->response.rlen - w->response.data->len; + ssize_t left = (ssize_t)(w->response.rlen - w->response.data->len); ssize_t bytes = read(w->ifd, &w->response.data->buffer[w->response.data->len], (size_t)left); if(likely(bytes > 0)) { size_t old = w->response.data->len; @@ -1896,7 +1896,7 @@ ssize_t web_client_receive(struct web_client *w) return web_client_read_file(w); ssize_t bytes; - ssize_t left = w->response.data->size - w->response.data->len; + ssize_t left = (ssize_t)(w->response.data->size - w->response.data->len); // do we have any space for more data? buffer_need_bytes(w->response.data, NETDATA_WEB_REQUEST_RECEIVE_SIZE); @@ -1928,10 +1928,32 @@ ssize_t web_client_receive(struct web_client *w) debug(D_WEB_CLIENT, "%llu: Received %zd bytes.", w->id, bytes); debug(D_WEB_DATA, "%llu: Received data: '%s'.", w->id, &w->response.data->buffer[old]); } - else { + else if (bytes < 0) { debug(D_WEB_CLIENT, "%llu: receive data failed.", w->id); WEB_CLIENT_IS_DEAD(w); - } + } else + debug(D_WEB_CLIENT, "%llu: Received %zd bytes.", w->id, bytes); return(bytes); } + + +int web_client_socket_is_now_used_for_streaming(struct web_client *w) { + // prevent the web_client from closing the streaming socket + + WEB_CLIENT_IS_DEAD(w); + + if(web_server_mode == WEB_SERVER_MODE_STATIC_THREADED) { + web_client_flag_set(w, WEB_CLIENT_FLAG_DONT_CLOSE_SOCKET); + } + else { + if(w->ifd == w->ofd) + w->ifd = w->ofd = -1; + else + w->ifd = -1; + } + + buffer_flush(w->response.data); + + return HTTP_RESP_OK; +} -- cgit v1.2.3