summaryrefslogtreecommitdiffstats
path: root/web/server/web_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'web/server/web_client.c')
-rw-r--r--web/server/web_client.c68
1 files changed, 45 insertions, 23 deletions
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;
+}