summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libnetdata/socket/security.h3
-rw-r--r--web/server/web_client.c17
-rw-r--r--web/server/web_client.h1
-rw-r--r--web/server/web_client_cache.c4
4 files changed, 20 insertions, 5 deletions
diff --git a/libnetdata/socket/security.h b/libnetdata/socket/security.h
index 01703d7863..6eee80324f 100644
--- a/libnetdata/socket/security.h
+++ b/libnetdata/socket/security.h
@@ -10,6 +10,7 @@
# define NETDATA_SSL_FORCE 32 //We only accepts HTTPS request
# define NETDATA_SSL_INVALID_CERTIFICATE 64 //Accepts invalid certificate
# define NETDATA_SSL_VALID_CERTIFICATE 128 //Accepts invalid certificate
+# define NETDATA_SSL_PROXY_HTTPS 256 //Proxy is using HTTPS
#define NETDATA_SSL_CONTEXT_SERVER 0
#define NETDATA_SSL_CONTEXT_STREAMING 1
@@ -30,7 +31,7 @@
struct netdata_ssl{
SSL *conn; //SSL connection
- int flags; //The flags for SSL connection
+ uint32_t flags; //The flags for SSL connection
};
extern SSL_CTX *netdata_opentsdb_ctx;
diff --git a/web/server/web_client.c b/web/server/web_client.c
index a0a3c9a557..9792de68ab 100644
--- a/web/server/web_client.c
+++ b/web/server/web_client.c
@@ -733,7 +733,8 @@ 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;
+ 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
@@ -748,6 +749,8 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u
hash_useragent = simple_uhash("User-Agent");
hash_authorization = simple_uhash("X-Auth-Token");
hash_host = simple_uhash("Host");
+ hash_forwarded_proto = simple_uhash("X-Forwarded-Proto");
+ hash_forwarded_host = simple_uhash("X-Forwarded-Host");
}
char *e = s;
@@ -809,6 +812,13 @@ static inline char *http_header_parse(struct web_client *w, char *s, int parse_u
}
}
#endif /* NETDATA_WITH_ZLIB */
+ else if(hash == hash_forwarded_proto && !strcasecmp(s, "X-Forwarded-Proto")) {
+ if(strcasestr(v, "https"))
+ w->ssl.flags |= NETDATA_SSL_PROXY_HTTPS;
+ }
+ else if(hash == hash_forwarded_host && !strcasecmp(s, "X-Forwarded-Host")){
+ strncpyz(w->forwarded_host, v, ((size_t)(ve - v) < sizeof(w->server_host)-1 ? (size_t)(ve - v) : sizeof(w->server_host)-1));
+ }
*e = ':';
*ve = '\r';
@@ -1345,7 +1355,10 @@ 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);
- buffer_sprintf(w->response.header, "Location: http://%s%s/\r\n", w->server_host, w->last_url);
+ char *protocol, *url_host;
+ protocol = ((w->ssl.conn && !w->ssl.flags) || w->ssl.flags & NETDATA_SSL_PROXY_HTTPS) ? "https" : "http";
+ url_host = (!w->forwarded_host[0])?w->server_host:w->forwarded_host;
+ buffer_sprintf(w->response.header, "Location: %s://%s%s/\r\n", protocol, url_host, w->last_url);
buffer_strcat(w->response.data, "Permanent redirect");
return HTTP_RESP_REDIR_PERM;
}
diff --git a/web/server/web_client.h b/web/server/web_client.h
index 9e3b851884..a8595853bf 100644
--- a/web/server/web_client.h
+++ b/web/server/web_client.h
@@ -155,6 +155,7 @@ struct web_client {
char client_port[NI_MAXSERV];
char server_host[NI_MAXHOST];
char client_host[NI_MAXHOST];
+ char forwarded_host[NI_MAXHOST]; //Used with proxy
char decoded_url[NETDATA_WEB_REQUEST_URL_SIZE + 1]; // we decode the URL in this buffer
char decoded_query_string[NETDATA_WEB_REQUEST_URL_SIZE + 1]; // we decode the Query String in this buffer
diff --git a/web/server/web_client_cache.c b/web/server/web_client_cache.c
index 763e7e96a7..afd51d854b 100644
--- a/web/server/web_client_cache.c
+++ b/web/server/web_client_cache.c
@@ -188,7 +188,7 @@ struct web_client *web_client_get_from_cache_or_allocate() {
#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 = %d)",w->ssl.flags);
+ debug(D_WEB_CLIENT_ACCESS,"Reusing SSL structure with (w->ssl = NULL, w->accepted = %u)", w->ssl.flags);
#endif
}
else {
@@ -196,7 +196,7 @@ struct web_client *web_client_get_from_cache_or_allocate() {
w = web_client_alloc();
#ifdef ENABLE_HTTPS
w->ssl.flags = NETDATA_SSL_START;
- debug(D_WEB_CLIENT_ACCESS,"Starting SSL structure with (w->ssl = NULL, w->accepted = %d)",w->ssl.flags);
+ debug(D_WEB_CLIENT_ACCESS,"Starting SSL structure with (w->ssl = NULL, w->accepted = %u)", w->ssl.flags);
#endif
web_clients_cache.allocated++;
}