[njs] HTTP: simplifed headers handling.
Dmitry Volyntsev
xeioex at nginx.com
Thu Apr 30 10:12:08 UTC 2020
details: https://hg.nginx.org/njs/rev/9e1caca2ee71
branches:
changeset: 1384:9e1caca2ee71
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Apr 30 09:44:00 2020 +0000
description:
HTTP: simplifed headers handling.
diffstat:
nginx/ngx_http_js_module.c | 328 +++++++++++++++++++-------------------------
1 files changed, 144 insertions(+), 184 deletions(-)
diffs (512 lines):
diff -r f35440bf511f -r 9e1caca2ee71 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c Wed Apr 29 11:57:11 2020 +0000
+++ b/nginx/ngx_http_js_module.c Thu Apr 30 09:44:00 2020 +0000
@@ -60,8 +60,8 @@ typedef struct {
typedef struct {
njs_str_t name;
njs_int_t (*handler)(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval,
- njs_value_t *retval);
+ ngx_list_t *headers, njs_str_t *name,
+ njs_value_t *setval, njs_value_t *retval);
} ngx_http_js_header_t;
@@ -87,25 +87,27 @@ static ngx_table_elt_t *ngx_http_js_get_
static njs_int_t ngx_http_js_ext_header_out(njs_vm_t *vm,
njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
njs_value_t *retval);
-static njs_int_t ngx_http_js_header_out_single(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *v, njs_value_t *setval,
- njs_value_t *retval);
+static njs_int_t ngx_http_js_header_single(njs_vm_t *vm,
+ ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
+ njs_value_t *setval, njs_value_t *retval);
static njs_int_t ngx_http_js_header_out_special(njs_vm_t *vm,
ngx_http_request_t *r, njs_str_t *v, njs_value_t *setval,
njs_value_t *retval, ngx_table_elt_t **hh);
-static njs_int_t ngx_http_js_header_out_array(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *v, njs_value_t *setval,
- njs_value_t *retval);
-static njs_int_t ngx_http_js_header_out_generic(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *v, njs_value_t *setval,
- njs_value_t *retval);
+static njs_int_t ngx_http_js_header_array(njs_vm_t *vm,
+ ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
+ njs_value_t *setval, njs_value_t *retval);
+static njs_int_t ngx_http_js_header_generic(njs_vm_t *vm,
+ ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
+ njs_value_t *setval, njs_value_t *retval);
static njs_int_t ngx_http_js_content_length(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval);
+ ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
+ njs_value_t *retval);
static njs_int_t ngx_http_js_content_encoding(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *name, njs_value_t *setval,
+ ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
+ njs_value_t *setval, njs_value_t *retval);
+static njs_int_t ngx_http_js_content_type(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
njs_value_t *retval);
-static njs_int_t ngx_http_js_content_type(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval);
static njs_int_t ngx_http_js_ext_keys_header_out(njs_vm_t *vm,
njs_value_t *value, njs_value_t *keys);
static njs_int_t ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop,
@@ -133,25 +135,19 @@ static njs_int_t ngx_http_js_ext_get_rem
static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm,
njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
njs_value_t *retval);
-static njs_int_t ngx_http_js_ext_get_header_in(njs_vm_t *vm,
+static njs_int_t ngx_http_js_ext_header_in(njs_vm_t *vm,
njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
njs_value_t *retval);
-static njs_int_t ngx_http_js_header_in_cookie(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *name, njs_value_t *setval,
- njs_value_t *retval);
+static njs_int_t ngx_http_js_header_cookie(njs_vm_t *vm,
+ ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
+ njs_value_t *setval, njs_value_t *retval);
#if (NGX_HTTP_X_FORWARDED_FOR)
-static njs_int_t ngx_http_js_header_in_x_forwarded_for(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *name, njs_value_t *setval,
- njs_value_t *retval);
+static njs_int_t ngx_http_js_header_x_forwarded_for(njs_vm_t *vm,
+ ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
+ njs_value_t *setval, njs_value_t *retval);
#endif
static njs_int_t ngx_http_js_header_in_array(njs_vm_t *vm,
ngx_http_request_t *r, ngx_array_t *array, u_char sep, njs_value_t *retval);
-static njs_int_t ngx_http_js_header_in_single(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *name, njs_value_t *setval,
- njs_value_t *retval);
-static njs_int_t ngx_http_js_header_in_generic(njs_vm_t *vm,
- ngx_http_request_t *r, njs_str_t *name, njs_value_t *setval,
- njs_value_t *retval);
static njs_int_t ngx_http_js_ext_keys_header_in(njs_vm_t *vm,
njs_value_t *value, njs_value_t *keys);
static njs_int_t ngx_http_js_ext_get_arg(njs_vm_t *vm,
@@ -352,7 +348,7 @@ static njs_external_t ngx_http_js_ext_r
.enumerable = 1,
.u.object = {
.enumerable = 1,
- .prop_handler = ngx_http_js_ext_get_header_in,
+ .prop_handler = ngx_http_js_ext_header_in,
.keys = ngx_http_js_ext_keys_header_in,
}
},
@@ -938,75 +934,6 @@ ngx_http_js_get_header(ngx_list_part_t *
static njs_int_t
-ngx_http_js_return_header(njs_vm_t *vm, ngx_http_request_t *r,
- ngx_list_part_t *part, njs_str_t *name, njs_value_t *retval)
-{
- size_t len;
- u_char *data, *p, *start, *end;
- ngx_uint_t i;
- ngx_table_elt_t *header, *h;
-
- header = part->elts;
-
- p = NULL;
- start = NULL;
- end = NULL;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- h = &header[i];
-
- if (h->hash == 0
- || h->key.len != name->length
- || ngx_strncasecmp(h->key.data, name->start, name->length) != 0)
- {
- continue;
- }
-
- if (p == NULL) {
- start = h->value.data;
- end = h->value.data + h->value.len;
- p = end;
- continue;
- }
-
- if (p + h->value.len + 1 > end) {
- len = njs_max(p + h->value.len + 1 - start, 2 * (end - start));
-
- data = ngx_pnalloc(r->pool, len);
- if (data == NULL) {
- return NJS_ERROR;
- }
-
- p = ngx_cpymem(data, start, p - start);
- start = data;
- end = data + len;
- }
-
- *p++ = ',';
- p = ngx_cpymem(p, h->value.data, h->value.len);
- }
-
- if (p == NULL) {
- njs_value_undefined_set(retval);
- return NJS_DECLINED;
- }
-
- return njs_vm_value_string_set(vm, retval, start, p - start);
-}
-
-
-static njs_int_t
ngx_http_js_ext_header_out(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
{
@@ -1016,17 +943,17 @@ ngx_http_js_ext_header_out(njs_vm_t *vm,
ngx_http_js_header_t *h;
static ngx_http_js_header_t headers_out[] = {
- { njs_str("Age"), ngx_http_js_header_out_single },
+ { njs_str("Age"), ngx_http_js_header_single },
{ njs_str("Content-Type"), ngx_http_js_content_type },
{ njs_str("Content-Length"), ngx_http_js_content_length },
{ njs_str("Content-Encoding"), ngx_http_js_content_encoding },
- { njs_str("Etag"), ngx_http_js_header_out_single },
- { njs_str("Expires"), ngx_http_js_header_out_single },
- { njs_str("Last-Modified"), ngx_http_js_header_out_single },
- { njs_str("Location"), ngx_http_js_header_out_single },
- { njs_str("Set-Cookie"), ngx_http_js_header_out_array },
- { njs_str("Retry-After"), ngx_http_js_header_out_single },
- { njs_str(""), ngx_http_js_header_out_generic },
+ { njs_str("Etag"), ngx_http_js_header_single },
+ { njs_str("Expires"), ngx_http_js_header_single },
+ { njs_str("Last-Modified"), ngx_http_js_header_single },
+ { njs_str("Location"), ngx_http_js_header_single },
+ { njs_str("Set-Cookie"), ngx_http_js_header_array },
+ { njs_str("Retry-After"), ngx_http_js_header_single },
+ { njs_str(""), ngx_http_js_header_generic },
};
r = njs_vm_external(vm, value);
@@ -1055,20 +982,34 @@ ngx_http_js_ext_header_out(njs_vm_t *vm,
}
}
- return h->handler(vm, r, &name, setval, retval);
+ return h->handler(vm, r, &r->headers_out.headers, &name, setval, retval);
}
static njs_int_t
-ngx_http_js_header_out_single(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_header_single(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
+ njs_value_t *retval)
{
+ njs_int_t rc;
+ ngx_table_elt_t *h;
+
if (retval != NULL && setval == NULL) {
- return ngx_http_js_header_out_special(vm, r, name, setval, retval,
- NULL);
+ h = ngx_http_js_get_header(&headers->part, name->start, name->length);
+ if (h == NULL) {
+ njs_value_undefined_set(retval);
+ return NJS_DECLINED;
+ }
+
+ rc = njs_vm_value_string_set(vm, retval, h->value.data, h->value.len);
+ if (rc != NJS_OK) {
+ return NJS_ERROR;
+ }
+
+ return NJS_OK;
}
- return ngx_http_js_header_out_generic(vm, r, name, setval, retval);
+ return ngx_http_js_header_generic(vm, r, headers, name, setval, retval);
}
@@ -1088,18 +1029,7 @@ ngx_http_js_header_out_special(njs_vm_t
headers = &r->headers_out.headers;
if (retval != NULL && setval == NULL) {
- h = ngx_http_js_get_header(&headers->part, v->start, v->length);
- if (h == NULL) {
- njs_value_undefined_set(retval);
- return NJS_DECLINED;
- }
-
- rc = njs_vm_value_string_set(vm, retval, h->value.data, h->value.len);
- if (rc != NJS_OK) {
- return NJS_ERROR;
- }
-
- return NJS_OK;
+ return ngx_http_js_header_single(vm, r, headers, v, setval, retval);
}
if (setval != NULL && njs_value_is_array(setval)) {
@@ -1162,20 +1092,18 @@ ngx_http_js_header_out_special(njs_vm_t
static njs_int_t
-ngx_http_js_header_out_array(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_header_array(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
+ njs_value_t *retval)
{
size_t len;
u_char *data;
njs_int_t rc;
ngx_uint_t i;
- ngx_list_t *headers;
njs_value_t *value;
ngx_list_part_t *part;
ngx_table_elt_t *header, *h;
- headers = &r->headers_out.headers;
-
if (retval != NULL && setval == NULL) {
rc = njs_vm_array_alloc(vm, retval, 4);
if (rc != NJS_OK) {
@@ -1224,30 +1152,86 @@ ngx_http_js_header_out_array(njs_vm_t *v
return NJS_OK;
}
- return ngx_http_js_header_out_generic(vm, r, name, setval, retval);
+ return ngx_http_js_header_generic(vm, r, headers, name, setval, retval);
}
static njs_int_t
-ngx_http_js_header_out_generic(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_header_generic(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
+ njs_value_t *retval)
{
- u_char *p;
+ u_char *data, *p, *start, *end;
+ size_t len;
int64_t length;
njs_value_t *array;
njs_int_t rc;
njs_str_t s;
- ngx_list_t *headers;
ngx_uint_t i;
ngx_list_part_t *part;
ngx_table_elt_t *header, *h;
njs_opaque_value_t lvalue;
- headers = &r->headers_out.headers;
part = &headers->part;
if (retval != NULL && setval == NULL) {
- return ngx_http_js_return_header(vm, r, part, name, retval);
+ header = part->elts;
+
+ p = NULL;
+ start = NULL;
+ end = NULL;
+
+ for (i = 0; /* void */ ; i++) {
+
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+
+ part = part->next;
+ header = part->elts;
+ i = 0;
+ }
+
+ h = &header[i];
+
+ if (h->hash == 0
+ || h->key.len != name->length
+ || ngx_strncasecmp(h->key.data, name->start, name->length) != 0)
+ {
+ continue;
+ }
+
+ if (p == NULL) {
+ start = h->value.data;
+ end = h->value.data + h->value.len;
+ p = end;
+ continue;
+ }
+
+ if (p + h->value.len + 1 > end) {
+ len = njs_max(p + h->value.len + 1 - start, 2 * (end - start));
+
+ data = ngx_pnalloc(r->pool, len);
+ if (data == NULL) {
+ return NJS_ERROR;
+ }
+
+ p = ngx_cpymem(data, start, p - start);
+ start = data;
+ end = data + len;
+ }
+
+ *p++ = ',';
+ p = ngx_cpymem(p, h->value.data, h->value.len);
+ }
+
+ if (p == NULL) {
+ njs_value_undefined_set(retval);
+ return NJS_DECLINED;
+ }
+
+ return njs_vm_value_string_set(vm, retval, start, p - start);
}
header = part->elts;
@@ -1345,8 +1329,8 @@ ngx_http_js_header_out_generic(njs_vm_t
static njs_int_t
-ngx_http_js_content_encoding(njs_vm_t *vm, ngx_http_request_t *r, njs_str_t *v,
- njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_content_encoding(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *v, njs_value_t *setval, njs_value_t *retval)
{
njs_int_t rc;
ngx_table_elt_t *h;
@@ -1365,8 +1349,8 @@ ngx_http_js_content_encoding(njs_vm_t *v
static njs_int_t
-ngx_http_js_content_length(njs_vm_t *vm, ngx_http_request_t *r, njs_str_t *v,
- njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_content_length(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *v, njs_value_t *setval, njs_value_t *retval)
{
u_char *p, *start;
njs_int_t rc;
@@ -1419,8 +1403,8 @@ ngx_http_js_content_length(njs_vm_t *vm,
static njs_int_t
-ngx_http_js_content_type(njs_vm_t *vm, ngx_http_request_t *r, njs_str_t *v,
- njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_content_type(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *v, njs_value_t *setval, njs_value_t *retval)
{
int64_t length;
njs_int_t rc;
@@ -1928,7 +1912,7 @@ done:
static njs_int_t
-ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
{
njs_int_t rc;
@@ -1937,18 +1921,18 @@ ngx_http_js_ext_get_header_in(njs_vm_t *
ngx_http_js_header_t *h;
static ngx_http_js_header_t headers_in[] = {
- { njs_str("Content-Type"), ngx_http_js_header_in_single },
- { njs_str("Cookie"), ngx_http_js_header_in_cookie },
- { njs_str("ETag"), ngx_http_js_header_in_single },
- { njs_str("From"), ngx_http_js_header_in_single },
- { njs_str("Max-Forwards"), ngx_http_js_header_in_single },
- { njs_str("Referer"), ngx_http_js_header_in_single },
- { njs_str("Proxy-Authorization"), ngx_http_js_header_in_single },
- { njs_str("User-Agent"), ngx_http_js_header_in_single },
+ { njs_str("Content-Type"), ngx_http_js_header_single },
+ { njs_str("Cookie"), ngx_http_js_header_cookie },
+ { njs_str("ETag"), ngx_http_js_header_single },
+ { njs_str("From"), ngx_http_js_header_single },
+ { njs_str("Max-Forwards"), ngx_http_js_header_single },
+ { njs_str("Referer"), ngx_http_js_header_single },
+ { njs_str("Proxy-Authorization"), ngx_http_js_header_single },
+ { njs_str("User-Agent"), ngx_http_js_header_single },
#if (NGX_HTTP_X_FORWARDED_FOR)
- { njs_str("X-Forwarded-For"), ngx_http_js_header_in_x_forwarded_for },
+ { njs_str("X-Forwarded-For"), ngx_http_js_header_x_forwarded_for },
#endif
- { njs_str(""), ngx_http_js_header_in_generic },
+ { njs_str(""), ngx_http_js_header_generic },
};
r = njs_vm_external(vm, value);
@@ -1977,13 +1961,14 @@ ngx_http_js_ext_get_header_in(njs_vm_t *
}
}
- return h->handler(vm, r, &name, setval, retval);
+ return h->handler(vm, r, &r->headers_in.headers, &name, setval, retval);
}
static njs_int_t
-ngx_http_js_header_in_cookie(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_header_cookie(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
+ njs_value_t *retval)
{
return ngx_http_js_header_in_array(vm, r, &r->headers_in.cookies,
';', retval);
@@ -1992,8 +1977,9 @@ ngx_http_js_header_in_cookie(njs_vm_t *v
#if (NGX_HTTP_X_FORWARDED_FOR)
static njs_int_t
-ngx_http_js_header_in_x_forwarded_for(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval)
+ngx_http_js_header_x_forwarded_for(njs_vm_t *vm, ngx_http_request_t *r,
+ ngx_list_t *headers, njs_str_t *name, njs_value_t *setval,
+ njs_value_t *retval)
{
return ngx_http_js_header_in_array(vm, r, &r->headers_in.x_forwarded_for,
',', retval);
@@ -2055,32 +2041,6 @@ ngx_http_js_header_in_array(njs_vm_t *vm
static njs_int_t
-ngx_http_js_header_in_single(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval)
-{
- ngx_table_elt_t *h;
-
- h = ngx_http_js_get_header(&r->headers_in.headers.part, name->start,
- name->length);
- if (h == NULL) {
- njs_value_undefined_set(retval);
- return NJS_DECLINED;
- }
-
- return njs_vm_value_string_set(vm, retval, h->value.data, h->value.len);
-}
-
-
-static njs_int_t
-ngx_http_js_header_in_generic(njs_vm_t *vm, ngx_http_request_t *r,
- njs_str_t *name, njs_value_t *setval, njs_value_t *retval)
-{
- return ngx_http_js_return_header(vm, r, &r->headers_in.headers.part, name,
- retval);
-}
-
-
-static njs_int_t
ngx_http_js_ext_keys_header_in(njs_vm_t *vm, njs_value_t *value,
njs_value_t *keys)
{
More information about the nginx-devel
mailing list