HTTP: generalized uri encoding.
No functional changes.
This commit is contained in:
@@ -207,6 +207,13 @@ typedef struct {
|
||||
} nxt_http_name_value_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
NXT_HTTP_URI_ENCODING_NONE = 0,
|
||||
NXT_HTTP_URI_ENCODING,
|
||||
NXT_HTTP_URI_ENCODING_PLUS
|
||||
} nxt_http_uri_encoding_t;
|
||||
|
||||
|
||||
typedef struct nxt_http_route_s nxt_http_route_t;
|
||||
typedef struct nxt_http_route_rule_s nxt_http_route_rule_t;
|
||||
typedef struct nxt_http_route_addr_rule_s nxt_http_route_addr_rule_t;
|
||||
@@ -324,6 +331,9 @@ nxt_int_t nxt_http_request_content_length(void *ctx, nxt_http_field_t *field,
|
||||
nxt_array_t *nxt_http_arguments_parse(nxt_http_request_t *r);
|
||||
nxt_array_t *nxt_http_cookies_parse(nxt_http_request_t *r);
|
||||
|
||||
int64_t nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name,
|
||||
nxt_bool_t case_sensitive, uint8_t encoding);
|
||||
|
||||
nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task,
|
||||
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf);
|
||||
nxt_http_action_t *nxt_http_action_create(nxt_task_t *task,
|
||||
|
||||
@@ -1024,3 +1024,86 @@ nxt_http_cookie(nxt_array_t *array, u_char *name, size_t name_length,
|
||||
|
||||
return nv;
|
||||
}
|
||||
|
||||
|
||||
int64_t
|
||||
nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name, nxt_bool_t case_sensitive,
|
||||
uint8_t encoding)
|
||||
{
|
||||
u_char c, *p, *src, *start, *end, plus;
|
||||
uint8_t d0, d1;
|
||||
uint32_t hash;
|
||||
nxt_str_t str;
|
||||
nxt_uint_t i;
|
||||
|
||||
str.length = name->length;
|
||||
|
||||
str.start = nxt_mp_nget(mp, str.length);
|
||||
if (nxt_slow_path(str.start == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = str.start;
|
||||
|
||||
hash = NXT_HTTP_FIELD_HASH_INIT;
|
||||
|
||||
if (encoding == NXT_HTTP_URI_ENCODING_NONE) {
|
||||
for (i = 0; i < name->length; i++) {
|
||||
c = name->start[i];
|
||||
*p++ = c;
|
||||
|
||||
c = case_sensitive ? c : nxt_lowcase(c);
|
||||
hash = nxt_http_field_hash_char(hash, c);
|
||||
}
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
plus = (encoding == NXT_HTTP_URI_ENCODING_PLUS) ? ' ' : '+';
|
||||
|
||||
start = name->start;
|
||||
end = start + name->length;
|
||||
|
||||
for (src = start; src < end; src++) {
|
||||
c = *src;
|
||||
|
||||
switch (c) {
|
||||
case '%':
|
||||
if (nxt_slow_path(end - src <= 2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
d0 = nxt_hex2int[src[1]];
|
||||
d1 = nxt_hex2int[src[2]];
|
||||
src += 2;
|
||||
|
||||
if (nxt_slow_path((d0 | d1) >= 16)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = (d0 << 4) + d1;
|
||||
*p++ = c;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
c = plus;
|
||||
*p++ = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
*p++ = c;
|
||||
break;
|
||||
}
|
||||
|
||||
c = case_sensitive ? c : nxt_lowcase(c);
|
||||
hash = nxt_http_field_hash_char(hash, c);
|
||||
}
|
||||
|
||||
str.length = p - str.start;
|
||||
|
||||
end:
|
||||
|
||||
*name = str;
|
||||
|
||||
return nxt_http_field_hash_end(hash) & 0xFFFF;
|
||||
}
|
||||
|
||||
@@ -40,13 +40,6 @@ typedef enum {
|
||||
} nxt_http_route_pattern_case_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
NXT_HTTP_ROUTE_ENCODING_NONE = 0,
|
||||
NXT_HTTP_ROUTE_ENCODING_URI,
|
||||
NXT_HTTP_ROUTE_ENCODING_URI_PLUS
|
||||
} nxt_http_route_encoding_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
nxt_conf_value_t *host;
|
||||
nxt_conf_value_t *uri;
|
||||
@@ -169,29 +162,29 @@ static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task,
|
||||
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
|
||||
static nxt_http_route_table_t *nxt_http_route_table_create(nxt_task_t *task,
|
||||
nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
|
||||
nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding);
|
||||
nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding);
|
||||
static nxt_http_route_ruleset_t *nxt_http_route_ruleset_create(nxt_task_t *task,
|
||||
nxt_mp_t *mp, nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object,
|
||||
nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding);
|
||||
nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding);
|
||||
static nxt_http_route_rule_t *nxt_http_route_rule_name_create(nxt_task_t *task,
|
||||
nxt_mp_t *mp, nxt_conf_value_t *rule_cv, nxt_str_t *name,
|
||||
nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding);
|
||||
nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding);
|
||||
static nxt_http_route_rule_t *nxt_http_route_rule_create(nxt_task_t *task,
|
||||
nxt_mp_t *mp, nxt_conf_value_t *cv, nxt_bool_t case_sensitive,
|
||||
nxt_http_route_pattern_case_t pattern_case,
|
||||
nxt_http_route_encoding_t encoding);
|
||||
nxt_http_uri_encoding_t encoding);
|
||||
static int nxt_http_pattern_compare(const void *one, const void *two);
|
||||
static int nxt_http_addr_pattern_compare(const void *one, const void *two);
|
||||
static nxt_int_t nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern,
|
||||
nxt_http_route_pattern_case_t pattern_case,
|
||||
nxt_http_route_encoding_t encoding);
|
||||
nxt_http_uri_encoding_t encoding);
|
||||
static nxt_int_t nxt_http_route_decode_str(nxt_str_t *str,
|
||||
nxt_http_route_encoding_t encoding);
|
||||
nxt_http_uri_encoding_t encoding);
|
||||
static nxt_int_t nxt_http_route_pattern_slice(nxt_array_t *slices,
|
||||
nxt_str_t *test,
|
||||
nxt_http_route_pattern_type_t type,
|
||||
nxt_http_route_encoding_t encoding,
|
||||
nxt_http_uri_encoding_t encoding,
|
||||
nxt_http_route_pattern_case_t pattern_case);
|
||||
|
||||
static nxt_int_t nxt_http_route_resolve(nxt_task_t *task,
|
||||
@@ -457,7 +450,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.scheme != NULL) {
|
||||
rule = nxt_http_route_rule_create(task, mp, mtcf.scheme, 1,
|
||||
NXT_HTTP_ROUTE_PATTERN_NOCASE,
|
||||
NXT_HTTP_ROUTE_ENCODING_NONE);
|
||||
NXT_HTTP_URI_ENCODING_NONE);
|
||||
if (rule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -470,7 +463,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.host != NULL) {
|
||||
rule = nxt_http_route_rule_create(task, mp, mtcf.host, 1,
|
||||
NXT_HTTP_ROUTE_PATTERN_LOWCASE,
|
||||
NXT_HTTP_ROUTE_ENCODING_NONE);
|
||||
NXT_HTTP_URI_ENCODING_NONE);
|
||||
if (rule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -484,7 +477,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.uri != NULL) {
|
||||
rule = nxt_http_route_rule_create(task, mp, mtcf.uri, 1,
|
||||
NXT_HTTP_ROUTE_PATTERN_NOCASE,
|
||||
NXT_HTTP_ROUTE_ENCODING_URI);
|
||||
NXT_HTTP_URI_ENCODING);
|
||||
if (rule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -498,7 +491,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.method != NULL) {
|
||||
rule = nxt_http_route_rule_create(task, mp, mtcf.method, 1,
|
||||
NXT_HTTP_ROUTE_PATTERN_UPCASE,
|
||||
NXT_HTTP_ROUTE_ENCODING_NONE);
|
||||
NXT_HTTP_URI_ENCODING_NONE);
|
||||
if (rule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -512,7 +505,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.headers != NULL) {
|
||||
table = nxt_http_route_table_create(task, mp, mtcf.headers,
|
||||
NXT_HTTP_ROUTE_HEADER, 0,
|
||||
NXT_HTTP_ROUTE_ENCODING_NONE);
|
||||
NXT_HTTP_URI_ENCODING_NONE);
|
||||
if (table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -524,7 +517,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.arguments != NULL) {
|
||||
table = nxt_http_route_table_create(task, mp, mtcf.arguments,
|
||||
NXT_HTTP_ROUTE_ARGUMENT, 1,
|
||||
NXT_HTTP_ROUTE_ENCODING_URI_PLUS);
|
||||
NXT_HTTP_URI_ENCODING_PLUS);
|
||||
if (table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -536,7 +529,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.cookies != NULL) {
|
||||
table = nxt_http_route_table_create(task, mp, mtcf.cookies,
|
||||
NXT_HTTP_ROUTE_COOKIE, 1,
|
||||
NXT_HTTP_ROUTE_ENCODING_NONE);
|
||||
NXT_HTTP_URI_ENCODING_NONE);
|
||||
if (table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -548,7 +541,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
if (mtcf.query != NULL) {
|
||||
rule = nxt_http_route_rule_create(task, mp, mtcf.query, 1,
|
||||
NXT_HTTP_ROUTE_PATTERN_NOCASE,
|
||||
NXT_HTTP_ROUTE_ENCODING_URI_PLUS);
|
||||
NXT_HTTP_URI_ENCODING_PLUS);
|
||||
if (rule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -690,7 +683,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
|
||||
static nxt_http_route_table_t *
|
||||
nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
|
||||
nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding)
|
||||
nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding)
|
||||
{
|
||||
size_t size;
|
||||
uint32_t i, n;
|
||||
@@ -729,7 +722,7 @@ nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
static nxt_http_route_ruleset_t *
|
||||
nxt_http_route_ruleset_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object,
|
||||
nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding)
|
||||
nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding)
|
||||
{
|
||||
size_t size;
|
||||
uint32_t i, n, next;
|
||||
@@ -777,12 +770,9 @@ nxt_http_route_ruleset_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
static nxt_http_route_rule_t *
|
||||
nxt_http_route_rule_name_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
nxt_conf_value_t *rule_cv, nxt_str_t *name, nxt_bool_t case_sensitive,
|
||||
nxt_http_route_encoding_t encoding)
|
||||
nxt_http_uri_encoding_t encoding)
|
||||
{
|
||||
u_char c, *p, *src, *start, *end, plus;
|
||||
uint8_t d0, d1;
|
||||
uint32_t hash;
|
||||
nxt_uint_t i;
|
||||
int64_t hash;
|
||||
nxt_http_route_rule_t *rule;
|
||||
|
||||
rule = nxt_http_route_rule_create(task, mp, rule_cv, case_sensitive,
|
||||
@@ -792,74 +782,15 @@ nxt_http_route_rule_name_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash = nxt_http_field_hash(mp, name, case_sensitive, encoding);
|
||||
if (nxt_slow_path(hash == -1)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rule->u.name.hash = hash;
|
||||
rule->u.name.start = name->start;
|
||||
rule->u.name.length = name->length;
|
||||
|
||||
p = nxt_mp_nget(mp, name->length);
|
||||
if (nxt_slow_path(p == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash = NXT_HTTP_FIELD_HASH_INIT;
|
||||
rule->u.name.start = p;
|
||||
|
||||
if (encoding == NXT_HTTP_ROUTE_ENCODING_NONE) {
|
||||
for (i = 0; i < name->length; i++) {
|
||||
c = name->start[i];
|
||||
*p++ = c;
|
||||
|
||||
c = case_sensitive ? c : nxt_lowcase(c);
|
||||
hash = nxt_http_field_hash_char(hash, c);
|
||||
}
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
plus = (encoding == NXT_HTTP_ROUTE_ENCODING_URI_PLUS) ? ' ' : '+';
|
||||
|
||||
start = name->start;
|
||||
end = start + name->length;
|
||||
|
||||
for (src = start; src < end; src++) {
|
||||
c = *src;
|
||||
|
||||
switch (c) {
|
||||
case '%':
|
||||
if (nxt_slow_path(end - src <= 2)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d0 = nxt_hex2int[src[1]];
|
||||
d1 = nxt_hex2int[src[2]];
|
||||
src += 2;
|
||||
|
||||
if (nxt_slow_path((d0 | d1) >= 16)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c = (d0 << 4) + d1;
|
||||
*p++ = c;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
c = plus;
|
||||
*p++ = c;
|
||||
break;
|
||||
|
||||
default:
|
||||
*p++ = c;
|
||||
break;
|
||||
}
|
||||
|
||||
c = case_sensitive ? c : nxt_lowcase(c);
|
||||
hash = nxt_http_field_hash_char(hash, c);
|
||||
}
|
||||
|
||||
rule->u.name.length = p - rule->u.name.start;
|
||||
|
||||
end:
|
||||
|
||||
rule->u.name.hash = nxt_http_field_hash_end(hash) & 0xFFFF;
|
||||
|
||||
return rule;
|
||||
}
|
||||
|
||||
@@ -868,7 +799,7 @@ static nxt_http_route_rule_t *
|
||||
nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
nxt_conf_value_t *cv, nxt_bool_t case_sensitive,
|
||||
nxt_http_route_pattern_case_t pattern_case,
|
||||
nxt_http_route_encoding_t encoding)
|
||||
nxt_http_uri_encoding_t encoding)
|
||||
{
|
||||
size_t size;
|
||||
uint32_t i, n;
|
||||
@@ -953,7 +884,7 @@ nxt_http_route_types_rule_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
{
|
||||
return nxt_http_route_rule_create(task, mp, types, 0,
|
||||
NXT_HTTP_ROUTE_PATTERN_LOWCASE,
|
||||
NXT_HTTP_ROUTE_ENCODING_NONE);
|
||||
NXT_HTTP_URI_ENCODING_NONE);
|
||||
}
|
||||
|
||||
|
||||
@@ -992,7 +923,7 @@ static nxt_int_t
|
||||
nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern,
|
||||
nxt_http_route_pattern_case_t pattern_case,
|
||||
nxt_http_route_encoding_t encoding)
|
||||
nxt_http_uri_encoding_t encoding)
|
||||
{
|
||||
u_char c, *p, *end;
|
||||
nxt_str_t test, tmp;
|
||||
@@ -1188,15 +1119,15 @@ nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp,
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_http_route_decode_str(nxt_str_t *str, nxt_http_route_encoding_t encoding)
|
||||
nxt_http_route_decode_str(nxt_str_t *str, nxt_http_uri_encoding_t encoding)
|
||||
{
|
||||
u_char *start, *end;
|
||||
|
||||
switch (encoding) {
|
||||
case NXT_HTTP_ROUTE_ENCODING_NONE:
|
||||
case NXT_HTTP_URI_ENCODING_NONE:
|
||||
break;
|
||||
|
||||
case NXT_HTTP_ROUTE_ENCODING_URI:
|
||||
case NXT_HTTP_URI_ENCODING:
|
||||
start = str->start;
|
||||
|
||||
end = nxt_decode_uri(start, start, str->length);
|
||||
@@ -1207,7 +1138,7 @@ nxt_http_route_decode_str(nxt_str_t *str, nxt_http_route_encoding_t encoding)
|
||||
str->length = end - start;
|
||||
break;
|
||||
|
||||
case NXT_HTTP_ROUTE_ENCODING_URI_PLUS:
|
||||
case NXT_HTTP_URI_ENCODING_PLUS:
|
||||
start = str->start;
|
||||
|
||||
end = nxt_decode_uri_plus(start, start, str->length);
|
||||
@@ -1228,9 +1159,8 @@ nxt_http_route_decode_str(nxt_str_t *str, nxt_http_route_encoding_t encoding)
|
||||
|
||||
static nxt_int_t
|
||||
nxt_http_route_pattern_slice(nxt_array_t *slices,
|
||||
nxt_str_t *test,
|
||||
nxt_http_route_pattern_type_t type,
|
||||
nxt_http_route_encoding_t encoding,
|
||||
nxt_str_t *test, nxt_http_route_pattern_type_t type,
|
||||
nxt_http_uri_encoding_t encoding,
|
||||
nxt_http_route_pattern_case_t pattern_case)
|
||||
{
|
||||
u_char *start;
|
||||
|
||||
Reference in New Issue
Block a user