summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStelios Fragkakis <52996999+stelfrag@users.noreply.github.com>2024-06-27 16:41:03 +0300
committerGitHub <noreply@github.com>2024-06-27 16:41:03 +0300
commit9f0c8c400e15d4200529551957309f8ffc27805a (patch)
tree4dd24451b4765c308cf52f05c717168ef474ee48 /src
parenta4adc506d39b9b9cd90af87613b31d87cc310974 (diff)
Fix proxy connect response (#18017)
* Fix proxy connect response * Handle CONNECT to mqtt * Fix typo
Diffstat (limited to 'src')
-rw-r--r--src/aclk/https_client.c59
-rw-r--r--src/aclk/https_client.h8
-rw-r--r--src/aclk/mqtt_websockets/mqtt_wss_client.c9
-rw-r--r--src/streaming/sender.c2
4 files changed, 47 insertions, 31 deletions
diff --git a/src/aclk/https_client.c b/src/aclk/https_client.c
index df647ce663..2bc768f24b 100644
--- a/src/aclk/https_client.c
+++ b/src/aclk/https_client.c
@@ -23,9 +23,9 @@ static const char *http_req_type_to_str(http_req_type_t req) {
#define TRANSFER_ENCODING_CHUNKED (-2)
-void http_parse_ctx_create(http_parse_ctx *ctx)
+void http_parse_ctx_create(http_parse_ctx *ctx, enum http_parse_state parse_state)
{
- ctx->state = HTTP_PARSE_INITIAL;
+ ctx->state = parse_state;
ctx->content_length = -1;
ctx->http_code = 0;
ctx->headers = c_rhash_new(0);
@@ -51,6 +51,7 @@ void http_parse_ctx_destroy(http_parse_ctx *ctx)
#define HTTP_LINE_TERM "\x0D\x0A"
#define RESP_PROTO "HTTP/1.1 "
+#define RESP_PROTO10 "HTTP/1.0 "
#define HTTP_KEYVAL_SEPARATOR ": "
#define HTTP_HDR_BUFFER_SIZE 1024
#define PORT_STR_MAX_BYTES 12
@@ -244,10 +245,20 @@ http_parse_rc parse_http_response(rbuf_t buf, http_parse_ctx *parse_ctx)
if (parse_ctx->state != HTTP_PARSE_CONTENT && !rbuf_find_bytes(buf, HTTP_LINE_TERM, strlen(HTTP_LINE_TERM), &idx))
return HTTP_PARSE_NEED_MORE_DATA;
switch (parse_ctx->state) {
+ case HTTP_PARSE_PROXY_CONNECT:
case HTTP_PARSE_INITIAL:
if (rbuf_memcmp_n(buf, RESP_PROTO, strlen(RESP_PROTO))) {
- netdata_log_error("Expected response to start with \"%s\"", RESP_PROTO);
- return HTTP_PARSE_ERROR;
+ if (parse_ctx->state == HTTP_PARSE_PROXY_CONNECT) {
+ if (rbuf_memcmp_n(buf, RESP_PROTO10, strlen(RESP_PROTO10))) {
+ netdata_log_error(
+ "Expected response to start with \"%s\" or \"%s\"", RESP_PROTO, RESP_PROTO10);
+ return HTTP_PARSE_ERROR;
+ }
+ }
+ else {
+ netdata_log_error("Expected response to start with \"%s\"", RESP_PROTO);
+ return HTTP_PARSE_ERROR;
+ }
}
rbuf_bump_tail(buf, strlen(RESP_PROTO));
if (rbuf_pop(buf, rc, 4) != 4) {
@@ -489,36 +500,36 @@ static int read_parse_response(https_req_ctx_t *ctx) {
return 0;
}
+static const char *http_methods[] = {
+ [HTTP_REQ_GET] = "GET ",
+ [HTTP_REQ_POST] = "POST ",
+ [HTTP_REQ_CONNECT] = "CONNECT ",
+};
+
+
#define TX_BUFFER_SIZE 8192
#define RX_BUFFER_SIZE (TX_BUFFER_SIZE*2)
static int handle_http_request(https_req_ctx_t *ctx) {
BUFFER *hdr = buffer_create(TX_BUFFER_SIZE, &netdata_buffers_statistics.buffers_aclk);
int rc = 0;
- http_parse_ctx_create(&ctx->parse_ctx);
+ http_req_type_t req_type = ctx->request->request_type;
- // Prepare data to send
- switch (ctx->request->request_type) {
- case HTTP_REQ_CONNECT:
- buffer_strcat(hdr, "CONNECT ");
- break;
- case HTTP_REQ_GET:
- buffer_strcat(hdr, "GET ");
- break;
- case HTTP_REQ_POST:
- buffer_strcat(hdr, "POST ");
- break;
- default:
- netdata_log_error("Unknown HTTPS request type!");
- rc = 1;
- goto err_exit;
+ if (req_type >= HTTP_REQ_INVALID) {
+ netdata_log_error("Unknown HTTPS request type!");
+ rc = 1;
+ goto err_exit;
}
+ buffer_strcat(hdr, http_methods[req_type]);
- if (ctx->request->request_type == HTTP_REQ_CONNECT) {
+ if (req_type == HTTP_REQ_CONNECT) {
buffer_strcat(hdr, ctx->request->host);
buffer_sprintf(hdr, ":%d", ctx->request->port);
- } else {
+ http_parse_ctx_create(&ctx->parse_ctx, HTTP_PARSE_PROXY_CONNECT);
+ }
+ else {
buffer_strcat(hdr, ctx->request->url);
+ http_parse_ctx_create(&ctx->parse_ctx, HTTP_PARSE_INITIAL);
}
buffer_strcat(hdr, HTTP_1_1 HTTP_ENDL);
@@ -527,7 +538,7 @@ static int handle_http_request(https_req_ctx_t *ctx) {
buffer_sprintf(hdr, "Host: %s\x0D\x0A", ctx->request->host);
buffer_strcat(hdr, "User-Agent: Netdata/rocks newhttpclient\x0D\x0A");
- if (ctx->request->request_type == HTTP_REQ_POST && ctx->request->payload && ctx->request->payload_size) {
+ if (req_type == HTTP_REQ_POST && ctx->request->payload && ctx->request->payload_size) {
buffer_sprintf(hdr, "Content-Length: %zu\x0D\x0A", ctx->request->payload_size);
}
if (ctx->request->proxy_username) {
@@ -558,7 +569,7 @@ static int handle_http_request(https_req_ctx_t *ctx) {
goto err_exit;
}
- if (ctx->request->request_type == HTTP_REQ_POST && ctx->request->payload && ctx->request->payload_size) {
+ if (req_type == HTTP_REQ_POST && ctx->request->payload && ctx->request->payload_size) {
if (https_client_write_all(ctx, ctx->request->payload, ctx->request->payload_size)) {
netdata_log_error("Couldn't write payload into SSL connection");
rc = 3;
diff --git a/src/aclk/https_client.h b/src/aclk/https_client.h
index 79d0a42b75..bc5ca30b8d 100644
--- a/src/aclk/https_client.h
+++ b/src/aclk/https_client.h
@@ -11,7 +11,8 @@
typedef enum http_req_type {
HTTP_REQ_GET = 0,
HTTP_REQ_POST,
- HTTP_REQ_CONNECT
+ HTTP_REQ_CONNECT,
+ HTTP_REQ_INVALID
} http_req_type_t;
typedef struct {
@@ -82,7 +83,8 @@ int https_request(https_req_t *request, https_req_response_t *response);
// we expose previously internal parser as this is usefull also from
// other parts of the code
enum http_parse_state {
- HTTP_PARSE_INITIAL = 0,
+ HTTP_PARSE_PROXY_CONNECT = 0,
+ HTTP_PARSE_INITIAL,
HTTP_PARSE_HEADERS,
HTTP_PARSE_CONTENT
};
@@ -118,7 +120,7 @@ typedef struct {
size_t chunk_got;
} http_parse_ctx;
-void http_parse_ctx_create(http_parse_ctx *ctx);
+void http_parse_ctx_create(http_parse_ctx *ctx, enum http_parse_state parse_state);
void http_parse_ctx_destroy(http_parse_ctx *ctx);
typedef enum {
diff --git a/src/aclk/mqtt_websockets/mqtt_wss_client.c b/src/aclk/mqtt_websockets/mqtt_wss_client.c
index bc67ae7f5b..f5b4025d76 100644
--- a/src/aclk/mqtt_websockets/mqtt_wss_client.c
+++ b/src/aclk/mqtt_websockets/mqtt_wss_client.c
@@ -314,6 +314,7 @@ static int cert_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
#define PROXY_CONNECT "CONNECT"
#define PROXY_HTTP "HTTP/1.1"
+#define PROXY_HTTP10 "HTTP/1.0"
#define HTTP_ENDLINE "\x0D\x0A"
#define HTTP_HDR_TERMINATOR "\x0D\x0A\x0D\x0A"
#define HTTP_CODE_LEN 4
@@ -326,14 +327,16 @@ static int http_parse_reply(mqtt_wss_client client, rbuf_t buf)
int idx;
if (rbuf_memcmp_n(buf, PROXY_HTTP, strlen(PROXY_HTTP))) {
- mws_error(client->log, "http_proxy expected reply with \"" PROXY_HTTP "\"");
- return 1;
+ if (rbuf_memcmp_n(buf, PROXY_HTTP10, strlen(PROXY_HTTP10))) {
+ mws_error(client->log, "http_proxy expected reply with \"" PROXY_HTTP "\" or \"" PROXY_HTTP10 "\"");
+ return 1;
+ }
}
rbuf_bump_tail(buf, strlen(PROXY_HTTP));
if (!rbuf_pop(buf, http_code_s, 1) || http_code_s[0] != 0x20) {
- mws_error(client->log, "http_proxy missing space after \"" PROXY_HTTP "\"");
+ mws_error(client->log, "http_proxy missing space after \"" PROXY_HTTP "\" or \"" PROXY_HTTP10 "\"");
return 2;
}
diff --git a/src/streaming/sender.c b/src/streaming/sender.c
index d4c3cc0009..3432e69276 100644
--- a/src/streaming/sender.c
+++ b/src/streaming/sender.c
@@ -672,7 +672,7 @@ static int rrdpush_http_upgrade_prelude(RRDHOST *host, struct sender_state *s) {
rbuf_push(buf, http, bytes);
http_parse_ctx ctx;
- http_parse_ctx_create(&ctx);
+ http_parse_ctx_create(&ctx, HTTP_PARSE_INITIAL);
ctx.flags |= HTTP_PARSE_FLAG_DONT_WAIT_FOR_CONTENT;
int rc;