aboutsummaryrefslogtreecommitdiff
path: root/nginx/ngx_http_js_module.c
diff options
context:
space:
mode:
authorDmitry Volyntsev <xeioex@nginx.com>2019-10-23 14:42:38 +0300
committerDmitry Volyntsev <xeioex@nginx.com>2019-10-23 14:42:38 +0300
commitc38f6ccfa8f2967f96cbac506783f6f1c20faa5c (patch)
tree64cd9d1b0ebf5e02b26282f36d6a93b26c1e0180 /nginx/ngx_http_js_module.c
parenta808134055c7839ba5f54a10fd7b6a9d32170236 (diff)
downloadnjs-c38f6ccfa8f2967f96cbac506783f6f1c20faa5c.tar.gz
njs-c38f6ccfa8f2967f96cbac506783f6f1c20faa5c.zip
Refactoring iteration over external objects.
Previously, two callbacks were required to support array-like iteration for external objects (foreach, next). Instead using only one callback (keys) to simplify.
Diffstat (limited to 'nginx/ngx_http_js_module.c')
-rw-r--r--nginx/ngx_http_js_module.c220
1 files changed, 93 insertions, 127 deletions
diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c
index d6502509..68c49b72 100644
--- a/nginx/ngx_http_js_module.c
+++ b/nginx/ngx_http_js_module.c
@@ -36,12 +36,6 @@ typedef struct {
typedef struct {
- ngx_list_part_t *part;
- ngx_uint_t item;
-} ngx_http_js_table_entry_t;
-
-
-typedef struct {
ngx_http_request_t *request;
njs_vm_event_t vm_event;
void *unused;
@@ -62,10 +56,8 @@ static void ngx_http_js_cleanup_vm(void *data);
static njs_int_t ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
-static njs_int_t ngx_http_js_ext_foreach_header(njs_vm_t *vm, void *obj,
- void *next, uintptr_t data);
-static njs_int_t ngx_http_js_ext_next_header(njs_vm_t *vm, njs_value_t *value,
- void *obj, void *next);
+static njs_int_t ngx_http_js_ext_keys_header(njs_vm_t *vm, void *obj,
+ njs_value_t *keys, uintptr_t data);
static ngx_table_elt_t *ngx_http_js_get_header(ngx_list_part_t *part,
u_char *data, size_t len);
static njs_int_t ngx_http_js_ext_get_header_out(njs_vm_t *vm,
@@ -74,8 +66,8 @@ static njs_int_t ngx_http_js_ext_set_header_out(njs_vm_t *vm, void *obj,
uintptr_t data, njs_str_t *value);
static njs_int_t ngx_http_js_ext_delete_header_out(njs_vm_t *vm, void *obj,
uintptr_t data, njs_bool_t delete);
-static njs_int_t ngx_http_js_ext_foreach_header_out(njs_vm_t *vm, void *obj,
- void *next); /*FIXME*/
+static njs_int_t ngx_http_js_ext_keys_header_out(njs_vm_t *vm, void *obj,
+ njs_value_t *keys); /*FIXME*/
static njs_int_t ngx_http_js_ext_get_status(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
static njs_int_t ngx_http_js_ext_set_status(njs_vm_t *vm, void *obj,
@@ -108,14 +100,12 @@ static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm,
njs_value_t *value, void *obj, uintptr_t data);
static njs_int_t ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
-static njs_int_t ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj,
- void *next); /*FIXME*/
+static njs_int_t ngx_http_js_ext_keys_header_in(njs_vm_t *vm, void *obj,
+ njs_value_t *keys); /*FIXME*/
static njs_int_t ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
-static njs_int_t ngx_http_js_ext_foreach_arg(njs_vm_t *vm, void *obj,
- void *next);
-static njs_int_t ngx_http_js_ext_next_arg(njs_vm_t *vm, njs_value_t *value,
- void *obj, void *next);
+static njs_int_t ngx_http_js_ext_keys_arg(njs_vm_t *vm, void *obj,
+ njs_value_t *keys);
static njs_int_t ngx_http_js_ext_get_variable(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
static njs_int_t ngx_http_js_ext_set_variable(njs_vm_t *vm, void *obj,
@@ -229,7 +219,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
offsetof(ngx_http_request_t, uri) },
{ njs_str("method"),
@@ -241,7 +230,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
offsetof(ngx_http_request_t, method_name) },
{ njs_str("httpVersion"),
@@ -253,7 +241,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
0 },
{ njs_str("remoteAddress"),
@@ -265,7 +252,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
0 },
{ njs_str("parent"),
@@ -277,7 +263,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
0 },
{ njs_str("requestBody"),
@@ -289,7 +274,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
0 },
{ njs_str("responseBody"),
@@ -301,7 +285,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
0 },
{ njs_str("headersIn"),
@@ -311,8 +294,7 @@ static njs_external_t ngx_http_js_ext_request[] = {
ngx_http_js_ext_get_header_in,
NULL,
NULL,
- ngx_http_js_ext_foreach_header_in,
- ngx_http_js_ext_next_header,
+ ngx_http_js_ext_keys_header_in,
NULL,
0 },
@@ -323,8 +305,7 @@ static njs_external_t ngx_http_js_ext_request[] = {
ngx_http_js_ext_get_arg,
NULL,
NULL,
- ngx_http_js_ext_foreach_arg,
- ngx_http_js_ext_next_arg,
+ ngx_http_js_ext_keys_arg,
NULL,
0 },
@@ -337,7 +318,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
0 },
{ njs_str("status"),
@@ -349,7 +329,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
offsetof(ngx_http_request_t, headers_out.status) },
{ njs_str("headersOut"),
@@ -359,8 +338,7 @@ static njs_external_t ngx_http_js_ext_request[] = {
ngx_http_js_ext_get_header_out,
ngx_http_js_ext_set_header_out,
ngx_http_js_ext_delete_header_out,
- ngx_http_js_ext_foreach_header_out,
- ngx_http_js_ext_next_header,
+ ngx_http_js_ext_keys_header_out,
NULL,
0 },
@@ -372,7 +350,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_subrequest,
0 },
@@ -384,7 +361,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_log,
0 },
@@ -396,7 +372,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_warn,
0 },
@@ -408,7 +383,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_error,
0 },
@@ -420,7 +394,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_send_header,
0 },
@@ -432,7 +405,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_send,
0 },
@@ -444,7 +416,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_finish,
0 },
@@ -456,7 +427,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_return,
0 },
@@ -468,7 +438,6 @@ static njs_external_t ngx_http_js_ext_request[] = {
NULL,
NULL,
NULL,
- NULL,
ngx_http_js_ext_internal_redirect,
0 },
};
@@ -485,7 +454,6 @@ static njs_external_t ngx_http_js_externals[] = {
NULL,
NULL,
NULL,
- NULL,
0 },
};
@@ -822,64 +790,79 @@ ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value, void *obj,
static njs_int_t
-ngx_http_js_ext_foreach_header(njs_vm_t *vm, void *obj, void *next,
+ngx_http_js_ext_keys_header(njs_vm_t *vm, void *obj, njs_value_t *keys,
uintptr_t data)
{
char *p = obj;
- ngx_list_t *headers;
- ngx_http_request_t *r;
- ngx_http_js_table_entry_t *entry, **e;
-
- r = (ngx_http_request_t *) obj;
+ njs_int_t rc, cookie, x_for;
+ ngx_uint_t item;
+ ngx_list_t *headers;
+ njs_value_t *value;
+ ngx_list_part_t *part;
+ ngx_table_elt_t *header, *h;
- entry = ngx_palloc(r->pool, sizeof(ngx_http_js_table_entry_t));
- if (entry == NULL) {
+ rc = njs_vm_array_alloc(vm, keys, 8);
+ if (rc != NJS_OK) {
return NJS_ERROR;
}
headers = (ngx_list_t *) (p + data);
+ part = &headers->part;
+ item = 0;
- entry->part = &headers->part;
- entry->item = 0;
+ cookie = 0;
+ x_for = 0;
- e = (ngx_http_js_table_entry_t **) next;
- *e = entry;
+ while (part) {
- return NJS_OK;
-}
+ if (item >= part->nelts) {
+ part = part->next;
+ item = 0;
+ continue;
+ }
+ header = part->elts;
+ h = &header[item++];
-static njs_int_t
-ngx_http_js_ext_next_header(njs_vm_t *vm, njs_value_t *value, void *obj,
- void *next)
-{
- ngx_http_js_table_entry_t **e = next;
+ if (h->hash == 0) {
+ continue;
+ }
- ngx_table_elt_t *header, *h;
- ngx_http_js_table_entry_t *entry;
+ if (h->key.len == njs_length("Cookie")
+ && ngx_strncasecmp(h->key.data, (u_char *) "Cookie",
+ h->key.len) == 0)
+ {
+ if (cookie) {
+ continue;
+ }
- entry = *e;
+ cookie = 1;
+ }
- while (entry->part) {
+ if (h->key.len == njs_length("X-Forwarded-For")
+ && ngx_strncasecmp(h->key.data, (u_char *) "X-Forwarded-For",
+ h->key.len) == 0)
+ {
+ if (x_for) {
+ continue;
+ }
- if (entry->item >= entry->part->nelts) {
- entry->part = entry->part->next;
- entry->item = 0;
- continue;
+ x_for = 1;
}
- header = entry->part->elts;
- h = &header[entry->item++];
-
- if (h->hash == 0) {
- continue;
+ value = njs_vm_array_push(vm, keys);
+ if (value == NULL) {
+ return NJS_ERROR;
}
- return njs_vm_value_string_set(vm, value, h->key.data, h->key.len);
+ rc = njs_vm_value_string_set(vm, value, h->key.data, h->key.len);
+ if (rc != NJS_OK) {
+ return NJS_ERROR;
+ }
}
- return NJS_DONE;
+ return NJS_OK;
}
@@ -1078,9 +1061,9 @@ ngx_http_js_ext_delete_header_out(njs_vm_t *vm, void *obj, uintptr_t data,
static njs_int_t
-ngx_http_js_ext_foreach_header_out(njs_vm_t *vm, void *obj, void *next)
+ngx_http_js_ext_keys_header_out(njs_vm_t *vm, void *obj, njs_value_t *keys)
{
- return ngx_http_js_ext_foreach_header(vm, obj, next,
+ return ngx_http_js_ext_keys_header(vm, obj, keys,
offsetof(ngx_http_request_t, headers_out.headers));
}
@@ -1604,9 +1587,9 @@ multi:
static njs_int_t
-ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj, void *next)
+ngx_http_js_ext_keys_header_in(njs_vm_t *vm, void *obj, njs_value_t *keys)
{
- return ngx_http_js_ext_foreach_header(vm, obj, next,
+ return ngx_http_js_ext_keys_header(vm, obj, keys,
offsetof(ngx_http_request_t, headers_in.headers));
}
@@ -1632,67 +1615,50 @@ ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value, void *obj,
static njs_int_t
-ngx_http_js_ext_foreach_arg(njs_vm_t *vm, void *obj, void *next)
+ngx_http_js_ext_keys_arg(njs_vm_t *vm, void *obj, njs_value_t *keys)
{
- ngx_str_t *entry, **e;
+ u_char *v, *p, *start, *end;
+ njs_int_t rc;
+ njs_value_t *value;
ngx_http_request_t *r;
r = (ngx_http_request_t *) obj;
- entry = ngx_palloc(r->pool, sizeof(ngx_str_t));
- if (entry == NULL) {
+ rc = njs_vm_array_alloc(vm, keys, 8);
+ if (rc != NJS_OK) {
return NJS_ERROR;
}
- *entry = r->args;
-
- e = (ngx_str_t **) next;
- *e = entry;
-
- return NJS_OK;
-}
-
-
-static njs_int_t
-ngx_http_js_ext_next_arg(njs_vm_t *vm, njs_value_t *value, void *obj,
- void *next)
-{
- ngx_str_t **e = next;
-
- size_t len;
- u_char *v, *p, *start, *end;
- ngx_str_t *entry;
-
- entry = *e;
-
- if (entry->len == 0) {
- return NJS_DONE;
- }
-
- start = entry->data;
- end = start + entry->len;
+ start = r->args.data;
+ end = start + r->args.len;
- p = ngx_strlchr(start, end, '&');
- if (p == NULL) {
- p = end;
- }
+ while (start < end) {
+ p = ngx_strlchr(start, end, '&');
+ if (p == NULL) {
+ p = end;
+ }
- v = ngx_strlchr(start, p, '=');
- if (v == NULL) {
- v = p;
- }
+ v = ngx_strlchr(start, p, '=');
+ if (v == NULL) {
+ v = p;
+ }
- len = v - start;
+ if (v != start) {
+ value = njs_vm_array_push(vm, keys);
+ if (value == NULL) {
+ return NJS_ERROR;
+ }
- if (p != end) {
- entry->data = &p[1];
- entry->len = end - entry->data;
+ rc = njs_vm_value_string_set(vm, value, start, v - start);
+ if (rc != NJS_OK) {
+ return NJS_ERROR;
+ }
+ }
- } else {
- entry->len = 0;
+ start = p + 1;
}
- return njs_vm_value_string_set(vm, value, start, len);
+ return NJS_OK;
}