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.c142
1 files changed, 38 insertions, 104 deletions
diff --git a/web/server/web_client.c b/web/server/web_client.c
index 8bc72e71..6e3c1225 100644
--- a/web/server/web_client.c
+++ b/web/server/web_client.c
@@ -8,9 +8,7 @@
int respect_web_browser_do_not_track_policy = 0;
char *web_x_frame_options = NULL;
-#ifdef NETDATA_WITH_ZLIB
int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
-#endif /* NETDATA_WITH_ZLIB */
inline int web_client_permission_denied(struct web_client *w) {
w->response.data->content_type = CT_TEXT_PLAIN;
@@ -36,11 +34,10 @@ static inline int web_client_crock_socket(struct web_client *w __maybe_unused) {
return 0;
}
-static inline void web_client_enable_wait_from_ssl(struct web_client *w, int bytes) {
- int ssl_err = SSL_get_error(w->ssl.conn, bytes);
- if (ssl_err == SSL_ERROR_WANT_READ)
+static inline void web_client_enable_wait_from_ssl(struct web_client *w) {
+ if (w->ssl.ssl_errno == SSL_ERROR_WANT_READ)
web_client_enable_ssl_wait_receive(w);
- else if (ssl_err == SSL_ERROR_WANT_WRITE)
+ else if (w->ssl.ssl_errno == SSL_ERROR_WANT_WRITE)
web_client_enable_ssl_wait_send(w);
else {
web_client_disable_ssl_wait_receive(w);
@@ -101,15 +98,6 @@ static void web_client_reset_allocations(struct web_client *w, bool free_all) {
freez(w->post_payload);
w->post_payload = NULL;
w->post_payload_size = 0;
-
-#ifdef ENABLE_HTTPS
- if ((!web_client_check_unix(w)) && (netdata_ssl_srv_ctx)) {
- if (w->ssl.conn) {
- SSL_free(w->ssl.conn);
- w->ssl.conn = NULL;
- }
- }
-#endif
}
else {
// the web client is to be re-used
@@ -123,7 +111,6 @@ static void web_client_reset_allocations(struct web_client *w, bool free_all) {
buffer_reset(w->response.data);
// leave w->post_payload
- // leave w->ssl
}
freez(w->server_host);
@@ -142,7 +129,6 @@ static void web_client_reset_allocations(struct web_client *w, bool free_all) {
w->auth_bearer_token = NULL;
// if we had enabled compression, release it
-#ifdef NETDATA_WITH_ZLIB
if(w->response.zinitialized) {
deflateEnd(&w->response.zstream);
w->response.zsent = 0;
@@ -154,7 +140,6 @@ static void web_client_reset_allocations(struct web_client *w, bool free_all) {
w->response.zinitialized = false;
w->flags &= ~WEB_CLIENT_CHUNKED_TRANSFER;
}
-#endif // NETDATA_WITH_ZLIB
}
void web_client_request_done(struct web_client *w) {
@@ -168,9 +153,7 @@ void web_client_request_done(struct web_client *w) {
size_t size = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->response.rlen:w->response.data->len;
size_t sent = size;
-#ifdef NETDATA_WITH_ZLIB
if(likely(w->response.zoutput)) sent = (size_t)w->response.zstream.total_out;
-#endif
// --------------------------------------------------------------------
// global statistics
@@ -444,9 +427,6 @@ int mysendfile(struct web_client *w, char *filename) {
}
#endif
-
-
-#ifdef NETDATA_WITH_ZLIB
void web_client_enable_deflate(struct web_client *w, int gzip) {
if(unlikely(w->response.zinitialized)) {
debug(D_DEFLATE, "%llu: Compression has already be initialized for this client.", w->id);
@@ -492,7 +472,6 @@ void web_client_enable_deflate(struct web_client *w, int gzip) {
debug(D_DEFLATE, "%llu: Initialized compression.", w->id);
}
-#endif // NETDATA_WITH_ZLIB
void buffer_data_options2string(BUFFER *wb, uint32_t options) {
int count = 0;
@@ -730,16 +709,12 @@ const char *web_response_code_to_string(int code) {
static inline char *http_header_parse(struct web_client *w, char *s, int parse_useragent) {
static uint32_t hash_origin = 0, hash_connection = 0, hash_donottrack = 0, hash_useragent = 0,
hash_authorization = 0, hash_host = 0, hash_forwarded_proto = 0, hash_forwarded_host = 0;
-#ifdef NETDATA_WITH_ZLIB
static uint32_t hash_accept_encoding = 0;
-#endif
if(unlikely(!hash_origin)) {
hash_origin = simple_uhash("Origin");
hash_connection = simple_uhash("Connection");
-#ifdef NETDATA_WITH_ZLIB
hash_accept_encoding = simple_uhash("Accept-Encoding");
-#endif
hash_donottrack = simple_uhash("DNT");
hash_useragent = simple_uhash("User-Agent");
hash_authorization = simple_uhash("X-Auth-Token");
@@ -798,7 +773,6 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u
strncpyz(buffer, v, ((size_t)(ve - v) < sizeof(buffer) - 1 ? (size_t)(ve - v) : sizeof(buffer) - 1));
w->server_host = strdupz(buffer);
}
-#ifdef NETDATA_WITH_ZLIB
else if(hash == hash_accept_encoding && !strcasecmp(s, "Accept-Encoding")) {
if(web_enable_gzip) {
if(strcasestr(v, "gzip"))
@@ -809,13 +783,10 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u
// web_client_enable_deflate(w, 0);
}
}
-#endif /* NETDATA_WITH_ZLIB */
-#ifdef ENABLE_HTTPS
else if(hash == hash_forwarded_proto && !strcasecmp(s, "X-Forwarded-Proto")) {
if(strcasestr(v, "https"))
- w->ssl.flags |= NETDATA_SSL_PROXY_HTTPS;
+ w->flags |= WEB_CLIENT_FLAG_PROXY_HTTPS;
}
-#endif
else if(hash == hash_forwarded_host && !strcasecmp(s, "X-Forwarded-Host")) {
char buffer[NI_MAXHOST];
strncpyz(buffer, v, ((size_t)(ve - v) < sizeof(buffer) - 1 ? (size_t)(ve - v) : sizeof(buffer) - 1));
@@ -855,7 +826,7 @@ static inline char *web_client_valid_method(struct web_client *w, char *s) {
s = &s[7];
#ifdef ENABLE_HTTPS
- if (w->ssl.flags && web_client_is_using_ssl_force(w)){
+ if (!SSL_connection(&w->ssl) && web_client_is_using_ssl_force(w)) {
w->header_parse_tries = 0;
w->header_parse_last_size = 0;
web_client_disable_wait_receive(w);
@@ -996,8 +967,8 @@ static inline HTTP_VALIDATION http_request_validate(struct web_client *w) {
*ue = c;
#ifdef ENABLE_HTTPS
- if ( (!web_client_check_unix(w)) && (netdata_ssl_srv_ctx) ) {
- if ((w->ssl.conn) && ((w->ssl.flags & NETDATA_SSL_NO_HANDSHAKE) && (web_client_is_using_ssl_force(w) || web_client_is_using_ssl_default(w)) && (w->mode != WEB_CLIENT_MODE_STREAM)) ) {
+ if ( (!web_client_check_unix(w)) && (netdata_ssl_web_server_ctx) ) {
+ if (!w->ssl.conn && (web_client_is_using_ssl_force(w) || web_client_is_using_ssl_default(w)) && (w->mode != WEB_CLIENT_MODE_STREAM)) {
w->header_parse_tries = 0;
w->header_parse_last_size = 0;
web_client_disable_wait_receive(w);
@@ -1026,16 +997,15 @@ static inline ssize_t web_client_send_data(struct web_client *w,const void *buf,
{
ssize_t bytes;
#ifdef ENABLE_HTTPS
- if ( (!web_client_check_unix(w)) && (netdata_ssl_srv_ctx) ) {
- if ( ( w->ssl.conn ) && ( !w->ssl.flags ) ){
- bytes = netdata_ssl_write(w->ssl.conn, buf, len) ;
- web_client_enable_wait_from_ssl(w, bytes);
- } else {
- bytes = send(w->ofd,buf, len , flags);
+ if ((!web_client_check_unix(w)) && (netdata_ssl_web_server_ctx)) {
+ if (SSL_connection(&w->ssl)) {
+ bytes = netdata_ssl_write(&w->ssl, buf, len) ;
+ web_client_enable_wait_from_ssl(w);
}
- } else {
+ else
+ bytes = send(w->ofd,buf, len , flags);
+ } else
bytes = send(w->ofd,buf, len , flags);
- }
#else
bytes = send(w->ofd, buf, len, flags);
#endif
@@ -1172,10 +1142,10 @@ static inline void web_client_send_http_header(struct web_client *w) {
size_t count = 0;
ssize_t bytes;
#ifdef ENABLE_HTTPS
- if ( (!web_client_check_unix(w)) && (netdata_ssl_srv_ctx) ) {
- if ( ( w->ssl.conn ) && ( w->ssl.flags == NETDATA_SSL_HANDSHAKE_COMPLETE ) ) {
- bytes = netdata_ssl_write(w->ssl.conn, buffer_tostring(w->response.header_output), buffer_strlen(w->response.header_output));
- web_client_enable_wait_from_ssl(w, bytes);
+ if ( (!web_client_check_unix(w)) && (netdata_ssl_web_server_ctx) ) {
+ if (SSL_connection(&w->ssl)) {
+ bytes = netdata_ssl_write(&w->ssl, buffer_tostring(w->response.header_output), buffer_strlen(w->response.header_output));
+ web_client_enable_wait_from_ssl(w);
}
else {
while((bytes = send(w->ofd, buffer_tostring(w->response.header_output), buffer_strlen(w->response.header_output), 0)) == -1) {
@@ -1276,11 +1246,11 @@ static inline int web_client_switch_host(RRDHOST *host, struct web_client *w, ch
if(!url) { //no delim found
debug(D_WEB_CLIENT, "%llu: URL doesn't end with / generating redirect.", w->id);
char *protocol, *url_host;
+ protocol = (
#ifdef ENABLE_HTTPS
- protocol = ((w->ssl.conn && !w->ssl.flags) || w->ssl.flags & NETDATA_SSL_PROXY_HTTPS) ? "https" : "http";
-#else
- protocol = "http";
+ SSL_connection(&w->ssl) ||
#endif
+ (w->flags & WEB_CLIENT_FLAG_PROXY_HTTPS)) ? "https" : "http";
url_host = w->forwarded_host;
if(!url_host) {
@@ -1736,7 +1706,6 @@ ssize_t web_client_send_chunk_finalize(struct web_client *w)
return bytes;
}
-#ifdef NETDATA_WITH_ZLIB
ssize_t web_client_send_deflate(struct web_client *w)
{
ssize_t len = 0, t = 0;
@@ -1851,12 +1820,9 @@ ssize_t web_client_send_deflate(struct web_client *w)
return(len);
}
-#endif // NETDATA_WITH_ZLIB
ssize_t web_client_send(struct web_client *w) {
-#ifdef NETDATA_WITH_ZLIB
if(likely(w->response.zoutput)) return web_client_send_deflate(w);
-#endif // NETDATA_WITH_ZLIB
ssize_t bytes;
@@ -1968,11 +1934,12 @@ ssize_t web_client_receive(struct web_client *w)
buffer_need_bytes(w->response.data, NETDATA_WEB_REQUEST_INITIAL_SIZE);
#ifdef ENABLE_HTTPS
- if ( (!web_client_check_unix(w)) && (netdata_ssl_srv_ctx) ) {
- if ( ( w->ssl.conn ) && (!w->ssl.flags)) {
- bytes = netdata_ssl_read(w->ssl.conn, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1));
- web_client_enable_wait_from_ssl(w, bytes);
- }else {
+ if ( (!web_client_check_unix(w)) && (netdata_ssl_web_server_ctx) ) {
+ if (SSL_connection(&w->ssl)) {
+ bytes = netdata_ssl_read(&w->ssl, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1));
+ web_client_enable_wait_from_ssl(w);
+ }
+ else {
bytes = recv(w->ifd, &w->response.data->buffer[w->response.data->len], (size_t) (left - 1), MSG_DONTWAIT);
}
}
@@ -2005,26 +1972,6 @@ ssize_t web_client_receive(struct web_client *w)
}
-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;
-}
-
void web_client_decode_path_and_query_string(struct web_client *w, const char *path_and_query_string) {
char buffer[NETDATA_WEB_REQUEST_URL_SIZE + 2];
buffer[0] = '\0';
@@ -2072,25 +2019,6 @@ void web_client_decode_path_and_query_string(struct web_client *w, const char *p
}
}
-#ifdef ENABLE_HTTPS
-void web_client_reuse_ssl(struct web_client *w) {
- if (netdata_ssl_srv_ctx) {
- if (w->ssl.conn) {
- SSL_SESSION *session = SSL_get_session(w->ssl.conn);
- SSL *old = w->ssl.conn;
- w->ssl.conn = SSL_new(netdata_ssl_srv_ctx);
- if (session) {
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_111
- if (SSL_SESSION_is_resumable(session))
-#endif
- SSL_set_session(w->ssl.conn, session);
- }
- SSL_free(old);
- }
- }
-}
-#endif
-
void web_client_zero(struct web_client *w) {
// zero everything about it - but keep the buffers
@@ -2105,8 +2033,7 @@ void web_client_zero(struct web_client *w) {
BUFFER *b6 = w->url_query_string_decoded;
#ifdef ENABLE_HTTPS
- web_client_reuse_ssl(w);
- SSL *ssl = w->ssl.conn;
+ NETDATA_SSL ssl = w->ssl;
#endif
size_t use_count = w->use_count;
@@ -2120,9 +2047,7 @@ void web_client_zero(struct web_client *w) {
w->use_count = use_count;
#ifdef ENABLE_HTTPS
- w->ssl.conn = ssl;
- w->ssl.flags = NETDATA_SSL_START;
- debug(D_WEB_CLIENT_ACCESS,"Reusing SSL structure with (w->ssl = NULL, w->accepted = %u)", w->ssl.flags);
+ w->ssl = ssl;
#endif
// restore the pointers of the buffers
@@ -2136,6 +2061,11 @@ void web_client_zero(struct web_client *w) {
struct web_client *web_client_create(size_t *statistics_memory_accounting) {
struct web_client *w = (struct web_client *)callocz(1, sizeof(struct web_client));
+
+#ifdef ENABLE_HTTPS
+ w->ssl = NETDATA_SSL_UNSET_CONNECTION;
+#endif
+
w->use_count = 1;
w->statistics.memory_accounting = statistics_memory_accounting;
@@ -2152,6 +2082,10 @@ struct web_client *web_client_create(size_t *statistics_memory_accounting) {
}
void web_client_free(struct web_client *w) {
+#ifdef ENABLE_HTTPS
+ netdata_ssl_close(&w->ssl);
+#endif
+
web_client_reset_allocations(w, true);
__atomic_sub_fetch(w->statistics.memory_accounting, sizeof(struct web_client), __ATOMIC_RELAXED);