From 64be8717bdc2f0f8f11cbb8d18a0f96d2c24c6d3 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Mon, 16 Sep 2019 20:17:42 +0300 Subject: Configuration: added ability to access object members with slashes. Now URI encoding can be used to escape "/" in the request path: GET /config/listeners/unix:%2Fpath%2Fto%2Fsocket/ --- src/nxt_http_parse.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/nxt_http_parse.c') diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 8b4bf47c..945f4e93 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -1046,12 +1046,25 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) if (ch >= '0' && ch <= '9') { ch = (u_char) ((high << 4) + ch - '0'); - if (ch == '%' || ch == '#') { + if (ch == '%') { state = sw_normal; - *u++ = ch; + *u++ = '%'; + + if (rp->encoded_slashes) { + *u++ = '2'; + *u++ = '5'; + } + + continue; + } + + if (ch == '#') { + state = sw_normal; + *u++ = '#'; continue; + } - } else if (ch == '\0') { + if (ch == '\0') { return NXT_HTTP_PARSE_INVALID; } @@ -1067,8 +1080,17 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) state = sw_normal; *u++ = ch; continue; + } + + if (ch == '/' && rp->encoded_slashes) { + state = sw_normal; + *u++ = '%'; + *u++ = '2'; + *u++ = p[-1]; /* 'f' or 'F' */ + continue; + } - } else if (ch == '+') { + if (ch == '+') { rp->plus_in_target = 1; } -- cgit From 2fb7a1bfb90c4c8d484e4b0c4bd5ae2a594fd6e1 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Mon, 16 Sep 2019 20:17:42 +0300 Subject: HTTP parser: removed unused "exten_start" and "args_start" fields. --- src/nxt_http_parse.c | 58 ++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'src/nxt_http_parse.c') diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 945f4e93..9d591b86 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -163,7 +163,7 @@ static nxt_int_t nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, u_char *end) { - u_char *p, ch, *after_slash; + u_char *p, ch, *after_slash, *exten, *args; nxt_int_t rc; nxt_http_ver_t ver; nxt_http_target_traps_e trap; @@ -255,6 +255,8 @@ nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, rp->target_start = p; after_slash = p + 1; + exten = NULL; + args = NULL; for ( ;; ) { p++; @@ -269,8 +271,7 @@ nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, } after_slash = p + 1; - - rp->exten_start = NULL; + exten = NULL; continue; case NXT_HTTP_TARGET_DOT: @@ -279,11 +280,11 @@ nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, goto rest_of_target; } - rp->exten_start = p + 1; + exten = p + 1; continue; case NXT_HTTP_TARGET_ARGS_MARK: - rp->args_start = p + 1; + args = p + 1; goto rest_of_target; case NXT_HTTP_TARGET_SPACE: @@ -437,20 +438,19 @@ space_after_target: rp->path.start = rp->target_start; - if (rp->args_start != NULL) { - rp->path.length = rp->args_start - rp->target_start - 1; + if (args != NULL) { + rp->path.length = args - rp->target_start - 1; - rp->args.start = rp->args_start; - rp->args.length = rp->target_end - rp->args_start; + rp->args.length = rp->target_end - args; + rp->args.start = args; } else { rp->path.length = rp->target_end - rp->target_start; } - if (rp->exten_start) { - rp->exten.length = rp->path.start + rp->path.length - - rp->exten_start; - rp->exten.start = rp->exten_start; + if (exten != NULL) { + rp->exten.length = (rp->path.start + rp->path.length) - exten; + rp->exten.start = exten; } return nxt_http_parse_field_name(rp, pos, end); @@ -835,7 +835,8 @@ static const uint8_t nxt_http_normal[32] nxt_aligned(32) = { static nxt_int_t nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) { - u_char *p, *u, c, ch, high; + u_char *p, *u, c, ch, high, *exten, *args; + enum { sw_normal = 0, sw_slash, @@ -852,7 +853,6 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) p = rp->target_start; u = nxt_mp_alloc(rp->mem_pool, rp->target_end - p + 1); - if (nxt_slow_path(u == NULL)) { return NXT_ERROR; } @@ -861,8 +861,8 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) rp->path.start = u; high = '\0'; - rp->exten_start = NULL; - rp->args_start = NULL; + exten = NULL; + args = NULL; while (p < rp->target_end) { @@ -881,7 +881,7 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) switch (ch) { case '/': - rp->exten_start = NULL; + exten = NULL; state = sw_slash; *u++ = ch; continue; @@ -890,12 +890,12 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) state = sw_quoted; continue; case '?': - rp->args_start = p; + args = p; goto args; case '#': goto done; case '.': - rp->exten_start = u + 1; + exten = u + 1; *u++ = ch; continue; case '+': @@ -928,7 +928,7 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) state = sw_quoted; continue; case '?': - rp->args_start = p; + args = p; goto args; case '#': goto done; @@ -965,7 +965,7 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) state = sw_quoted; continue; case '?': - rp->args_start = p; + args = p; goto args; case '#': goto done; @@ -1009,7 +1009,7 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) state = sw_quoted; continue; case '?': - rp->args_start = p; + args = p; goto args; case '#': goto done; @@ -1114,18 +1114,18 @@ args: } } - if (rp->args_start != NULL) { - rp->args.length = p - rp->args_start; - rp->args.start = rp->args_start; + if (args != NULL) { + rp->args.length = p - args; + rp->args.start = args; } done: rp->path.length = u - rp->path.start; - if (rp->exten_start) { - rp->exten.length = u - rp->exten_start; - rp->exten.start = rp->exten_start; + if (exten) { + rp->exten.length = u - exten; + rp->exten.start = exten; } return NXT_OK; -- cgit From 3b77e402a903d9f7a6eeb32f7930d8979f8e0c9e Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Mon, 16 Sep 2019 20:17:42 +0300 Subject: HTTP parser: removed unused "plus_in_target" flag. --- src/nxt_http_parse.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'src/nxt_http_parse.c') diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 9d591b86..4d806c61 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -47,7 +47,6 @@ typedef enum { NXT_HTTP_TARGET_DOT, /* . */ NXT_HTTP_TARGET_ARGS_MARK, /* ? */ NXT_HTTP_TARGET_QUOTE_MARK, /* % */ - NXT_HTTP_TARGET_PLUS, /* + */ } nxt_http_target_traps_e; @@ -57,7 +56,7 @@ static const uint8_t nxt_http_target_chars[256] nxt_aligned(64) = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* \s ! " # $ % & ' ( ) * + , - . / */ - 1, 0, 0, 2, 0, 8, 0, 0, 0, 0, 0, 9, 0, 0, 6, 5, + 1, 0, 0, 2, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, @@ -295,10 +294,6 @@ nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, rp->quoted_target = 1; goto rest_of_target; - case NXT_HTTP_TARGET_PLUS: - rp->plus_in_target = 1; - continue; - case NXT_HTTP_TARGET_HASH: rp->complex_target = 1; goto rest_of_target; @@ -898,9 +893,6 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) exten = u + 1; *u++ = ch; continue; - case '+': - rp->plus_in_target = 1; - /* Fall through. */ default: *u++ = ch; continue; @@ -932,9 +924,6 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) goto args; case '#': goto done; - case '+': - rp->plus_in_target = 1; - /* Fall through. */ default: state = sw_normal; *u++ = ch; @@ -969,9 +958,6 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) goto args; case '#': goto done; - case '+': - rp->plus_in_target = 1; - /* Fall through. */ default: state = sw_normal; *u++ = ch; @@ -1013,9 +999,6 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) goto args; case '#': goto done; - case '+': - rp->plus_in_target = 1; - /* Fall through. */ default: state = sw_normal; *u++ = ch; @@ -1090,10 +1073,6 @@ nxt_http_parse_complex_target(nxt_http_request_parse_t *rp) continue; } - if (ch == '+') { - rp->plus_in_target = 1; - } - state = saved_state; goto again; } -- cgit From 6352c21a58d66db99f8f981c37e6d57e62fc24a2 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Tue, 17 Sep 2019 18:40:21 +0300 Subject: HTTP parser: fixed parsing of target after literal space character. In theory, all space characters in request target must be encoded; however, some clients may violate the specification. For the sake of interoperability, Unit supports unencoded space characters. Previously, if there was a space character before the extension or arguments parts, those parts weren't recognized. Also, quoted symbols and complex target weren't detected after a space character. --- src/nxt_http_parse.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/nxt_http_parse.c') diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 4d806c61..5b009d96 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -164,6 +164,7 @@ nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, { u_char *p, ch, *after_slash, *exten, *args; nxt_int_t rc; + nxt_bool_t rest; nxt_http_ver_t ver; nxt_http_target_traps_e trap; @@ -256,6 +257,9 @@ nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, after_slash = p + 1; exten = NULL; args = NULL; + rest = 0; + +continue_target: for ( ;; ) { p++; @@ -312,6 +316,8 @@ nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, rest_of_target: + rest = 1; + for ( ;; ) { p++; @@ -378,7 +384,12 @@ space_after_target: } rp->space_in_target = 1; - goto rest_of_target; + + if (rest) { + goto rest_of_target; + } + + goto continue_target; } /* " HTTP/1.1\r\n" or " HTTP/1.1\n" */ @@ -392,7 +403,12 @@ space_after_target: } rp->space_in_target = 1; - goto rest_of_target; + + if (rest) { + goto rest_of_target; + } + + goto continue_target; } nxt_memcpy(ver.str, &p[1], 8); -- cgit