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/
This commit is contained in:
@@ -416,10 +416,13 @@ static void nxt_conf_path_next_token(nxt_conf_path_parse_t *parse,
|
||||
nxt_conf_value_t *
|
||||
nxt_conf_get_path(nxt_conf_value_t *value, nxt_str_t *path)
|
||||
{
|
||||
u_char *end;
|
||||
nxt_str_t token;
|
||||
nxt_int_t index;
|
||||
nxt_conf_path_parse_t parse;
|
||||
|
||||
u_char buf[256];
|
||||
|
||||
parse.start = path->start;
|
||||
parse.end = path->start + path->length;
|
||||
parse.last = 0;
|
||||
@@ -436,6 +439,18 @@ nxt_conf_get_path(nxt_conf_value_t *value, nxt_str_t *path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nxt_slow_path(token.length > 256)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
end = nxt_decode_uri(buf, token.start, token.length);
|
||||
if (nxt_slow_path(end == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
token.length = end - buf;
|
||||
token.start = buf;
|
||||
|
||||
switch (value->type) {
|
||||
|
||||
case NXT_CONF_VALUE_OBJECT:
|
||||
|
||||
@@ -478,6 +478,8 @@ nxt_controller_conn_init(nxt_task_t *task, void *obj, void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
r->parser.encoded_slashes = 1;
|
||||
|
||||
b = nxt_buf_mem_alloc(c->mem_pool, 1024, 0);
|
||||
if (nxt_slow_path(b == NULL)) {
|
||||
nxt_controller_conn_free(task, c, NULL);
|
||||
|
||||
@@ -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;
|
||||
continue;
|
||||
*u++ = '%';
|
||||
|
||||
} else if (ch == '\0') {
|
||||
if (rp->encoded_slashes) {
|
||||
*u++ = '2';
|
||||
*u++ = '5';
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '#') {
|
||||
state = sw_normal;
|
||||
*u++ = '#';
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} else if (ch == '+') {
|
||||
if (ch == '/' && rp->encoded_slashes) {
|
||||
state = sw_normal;
|
||||
*u++ = '%';
|
||||
*u++ = '2';
|
||||
*u++ = p[-1]; /* 'f' or 'F' */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '+') {
|
||||
rp->plus_in_target = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ struct nxt_http_request_parse_s {
|
||||
unsigned space_in_target:1;
|
||||
/* target with "+" */
|
||||
unsigned plus_in_target:1;
|
||||
|
||||
/* Preserve encoded '/' (%2F) and '%' (%25). */
|
||||
unsigned encoded_slashes:1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -451,3 +451,59 @@ nxt_strvers_match(u_char *version, u_char *prefix, size_t length)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u_char *
|
||||
nxt_decode_uri(u_char *dst, u_char *src, size_t length)
|
||||
{
|
||||
u_char *end, ch;
|
||||
uint8_t d0, d1;
|
||||
|
||||
static const uint8_t hex[256]
|
||||
nxt_aligned(32) =
|
||||
{
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 16, 16, 16, 16, 16,
|
||||
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
};
|
||||
|
||||
nxt_prefetch(&hex['0']);
|
||||
|
||||
end = src + length;
|
||||
|
||||
while (src < end) {
|
||||
ch = *src++;
|
||||
|
||||
if (ch == '%') {
|
||||
if (nxt_slow_path(end - src < 2)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d0 = hex[*src++];
|
||||
d1 = hex[*src++];
|
||||
|
||||
if (nxt_slow_path((d0 | d1) >= 16)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch = (d0 << 4) + d1;
|
||||
}
|
||||
|
||||
*dst++ = ch;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -168,5 +168,7 @@ NXT_EXPORT nxt_int_t nxt_strverscmp(const u_char *s1, const u_char *s2);
|
||||
NXT_EXPORT nxt_bool_t nxt_strvers_match(u_char *version, u_char *prefix,
|
||||
size_t length);
|
||||
|
||||
NXT_EXPORT u_char *nxt_decode_uri(u_char *dst, u_char *src, size_t length);
|
||||
|
||||
|
||||
#endif /* _NXT_STRING_H_INCLUDED_ */
|
||||
|
||||
Reference in New Issue
Block a user