#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
-
-#include <njs.h>
+#include "ngx_js.h"
typedef struct {
static void ngx_http_js_cleanup_ctx(void *data);
static void ngx_http_js_cleanup_vm(void *data);
-static njs_int_t ngx_http_js_ext_get_string(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_keys_header(njs_vm_t *vm, njs_value_t *value,
njs_value_t *keys, ngx_list_t *headers);
static ngx_table_elt_t *ngx_http_js_get_header(ngx_list_part_t *part,
static void ngx_http_js_timer_handler(ngx_event_t *ev);
static void ngx_http_js_handle_event(ngx_http_request_t *r,
njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs);
-static njs_int_t ngx_http_js_string(njs_vm_t *vm, njs_value_t *value,
- njs_str_t *str);
static char *ngx_http_js_include(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
.name.string = njs_str("uri"),
.enumerable = 1,
.u.property = {
- .handler = ngx_http_js_ext_get_string,
+ .handler = ngx_js_ext_string,
.magic32 = offsetof(ngx_http_request_t, uri),
}
},
.name.string = njs_str("method"),
.enumerable = 1,
.u.property = {
- .handler = ngx_http_js_ext_get_string,
+ .handler = ngx_js_ext_string,
.magic32 = offsetof(ngx_http_request_t, method_name),
}
},
ngx_http_js_content_event_handler(ngx_http_request_t *r)
{
ngx_int_t rc;
- njs_str_t name, exception;
- njs_function_t *func;
ngx_http_js_ctx_t *ctx;
ngx_http_js_loc_conf_t *jlcf;
ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
- name.start = jlcf->content.data;
- name.length = jlcf->content.len;
-
- func = njs_vm_function(ctx->vm, &name);
- if (func == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "js function \"%V\" not found", &jlcf->content);
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
/*
* status is expected to be overriden by finish(), return() or
* internalRedirect() methods, otherwise the content handler is
ctx->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- if (njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->request), 1) != NJS_OK) {
- njs_vm_retval_string(ctx->vm, &exception);
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "js exception: %*s", exception.length, exception.start);
+ rc = ngx_js_call(ctx->vm, &jlcf->content, &ctx->request,
+ r->connection->log);
+ if (rc == NGX_ERROR) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
- if (njs_vm_pending(ctx->vm)) {
+ if (rc == NGX_AGAIN) {
r->write_event_handler = ngx_http_js_content_write_event_handler;
return;
}
ngx_int_t rc;
njs_int_t pending;
- njs_str_t name, value, exception;
- njs_function_t *func;
+ njs_str_t value;
ngx_http_js_ctx_t *ctx;
rc = ngx_http_js_init_vm(r);
ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
- name.start = fname->data;
- name.length = fname->len;
-
- func = njs_vm_function(ctx->vm, &name);
- if (func == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "js function \"%V\" not found", fname);
- v->not_found = 1;
- return NGX_OK;
- }
-
pending = njs_vm_pending(ctx->vm);
- if (njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->request), 1) != NJS_OK) {
- njs_vm_retval_string(ctx->vm, &exception);
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "js exception: %*s", exception.length, exception.start);
+ rc = ngx_js_call(ctx->vm, fname, &ctx->request, r->connection->log);
+ if (rc == NGX_ERROR) {
v->not_found = 1;
return NGX_OK;
}
- if (njs_vm_retval_string(ctx->vm, &value) != NJS_OK) {
+ if (!pending && rc == NGX_AGAIN) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "async operation inside \"%V\" variable handler", fname);
return NGX_ERROR;
}
- if (!pending && njs_vm_pending(ctx->vm)) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "async operation inside \"%V\" variable handler", fname);
+ if (njs_vm_retval_string(ctx->vm, &value) != NJS_OK) {
return NGX_ERROR;
}
}
-static njs_int_t
-ngx_http_js_ext_get_string(njs_vm_t *vm, njs_object_prop_t *prop,
- njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
-{
- char *p;
- ngx_str_t *field;
-
- p = njs_vm_external(vm, value);
- if (p == NULL) {
- njs_value_undefined_set(retval);
- return NJS_DECLINED;
- }
-
- field = (ngx_str_t *) (p + njs_vm_prop_magic32(prop));
-
- return njs_vm_value_string_set(vm, retval, field->data, field->len);
-}
-
-
static njs_int_t
ngx_http_js_ext_keys_header(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys,
ngx_list_t *headers)
setval = njs_vm_array_prop(vm, setval, length - 1, &lvalue);
}
- rc = ngx_http_js_string(vm, setval, &s);
- if (rc != NJS_OK) {
+ if (ngx_js_string(vm, setval, &s) != NGX_OK) {
return NJS_ERROR;
}
setval = njs_vm_array_prop(vm, array, i, &lvalue);
}
- rc = ngx_http_js_string(vm, setval, &s);
- if (rc != NJS_OK) {
+ if (ngx_js_string(vm, setval, &s) != NGX_OK) {
return NJS_ERROR;
}
setval = njs_vm_array_prop(vm, setval, length - 1, &lvalue);
}
- rc = ngx_http_js_string(vm, setval, &s);
- if (rc != NJS_OK) {
+ if (ngx_js_string(vm, setval, &s) != NGX_OK) {
return NJS_ERROR;
}
ngx_http_js_ext_status(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;
ngx_int_t n;
- njs_str_t s;
ngx_http_request_t *r;
r = njs_vm_external(vm, value);
return NJS_OK;
}
- rc = ngx_http_js_string(vm, setval, &s);
- if (rc != NJS_OK) {
- return NJS_ERROR;
- }
-
- n = ngx_atoi(s.start, s.length);
- if (n == NGX_ERROR) {
+ if (ngx_js_integer(vm, setval, &n) != NGX_OK) {
return NJS_ERROR;
}
{
njs_str_t text;
ngx_int_t status;
- njs_value_t *value;
ngx_http_js_ctx_t *ctx;
ngx_http_request_t *r;
ngx_http_complex_value_t cv;
return NJS_ERROR;
}
- value = njs_arg(args, nargs, 1);
- if (!njs_value_is_valid_number(value)) {
- njs_vm_error(vm, "code is not a number");
+ if (ngx_js_integer(vm, njs_arg(args, nargs, 1), &status) != NGX_OK) {
return NJS_ERROR;
}
- status = njs_value_number(value);
-
if (status < 0 || status > 999) {
njs_vm_error(vm, "code is out of range");
return NJS_ERROR;
}
- if (ngx_http_js_string(vm, njs_arg(args, nargs, 2), &text) != NJS_OK) {
+ if (ngx_js_string(vm, njs_arg(args, nargs, 2), &text) != NGX_OK) {
njs_vm_error(vm, "failed to convert text");
return NJS_ERROR;
}
ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
- if (ngx_http_js_string(vm, njs_arg(args, nargs, 1), &uri) != NJS_OK) {
+ if (ngx_js_string(vm, njs_arg(args, nargs, 1), &uri) != NGX_OK) {
njs_vm_error(vm, "failed to convert uri arg");
return NJS_ERROR;
}
return NJS_ERROR;
}
- rc = ngx_http_js_string(vm, setval, &s);
- if (rc != NJS_OK) {
+ if (ngx_js_string(vm, setval, &s) != NGX_OK) {
return NJS_ERROR;
}
return NJS_ERROR;
}
- if (ngx_http_js_string(vm, njs_arg(args, nargs, 1), &uri_arg) != NJS_OK) {
+ if (ngx_js_string(vm, njs_arg(args, nargs, 1), &uri_arg) != NGX_OK) {
njs_vm_error(vm, "failed to convert uri arg");
return NJS_ERROR;
}
if (options != NULL) {
value = njs_vm_object_prop(vm, options, &args_key, &lvalue);
if (value != NULL) {
- if (ngx_http_js_string(vm, value, &args_arg) != NJS_OK) {
+ if (ngx_js_string(vm, value, &args_arg) != NGX_OK) {
njs_vm_error(vm, "failed to convert options.args");
return NJS_ERROR;
}
value = njs_vm_object_prop(vm, options, &method_key, &lvalue);
if (value != NULL) {
- if (ngx_http_js_string(vm, value, &method_name) != NJS_OK) {
+ if (ngx_js_string(vm, value, &method_name) != NGX_OK) {
njs_vm_error(vm, "failed to convert options.method");
return NJS_ERROR;
}
value = njs_vm_object_prop(vm, options, &body_key, &lvalue);
if (value != NULL) {
- if (ngx_http_js_string(vm, value, &body_arg) != NJS_OK) {
+ if (ngx_js_string(vm, value, &body_arg) != NGX_OK) {
njs_vm_error(vm, "failed to convert options.body");
return NJS_ERROR;
}
}
-static njs_int_t
-ngx_http_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str)
-{
- if (value != NULL && !njs_value_is_null_or_undefined(value)) {
- if (njs_vm_value_to_string(vm, str, value) == NJS_ERROR) {
- return NJS_ERROR;
- }
-
- } else {
- str->start = NULL;
- str->length = 0;
- }
-
- return NJS_OK;
-}
-
-
static char *
ngx_http_js_init_main_conf(ngx_conf_t *cf, void *conf)
{
--- /dev/null
+
+/*
+ * Copyright (C) Roman Arutyunyan
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include "ngx_js.h"
+
+
+ngx_int_t
+ngx_js_call(njs_vm_t *vm, ngx_str_t *fname, njs_opaque_value_t *value,
+ ngx_log_t *log)
+{
+ njs_str_t name, exception;
+ njs_function_t *func;
+
+ name.start = fname->data;
+ name.length = fname->len;
+
+ func = njs_vm_function(vm, &name);
+ if (func == NULL) {
+ ngx_log_error(NGX_LOG_ERR, log, 0,
+ "js function \"%V\" not found", fname);
+ return NGX_ERROR;
+ }
+
+ if (njs_vm_call(vm, func, njs_value_arg(value), 1) != NJS_OK) {
+ njs_vm_retval_string(vm, &exception);
+
+ ngx_log_error(NGX_LOG_ERR, log, 0,
+ "js exception: %*s", exception.length, exception.start);
+
+ return NGX_ERROR;
+ }
+
+ if (njs_vm_pending(vm)) {
+ return NGX_AGAIN;
+ }
+
+ return NGX_OK;
+}
+
+
+njs_int_t
+ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
+ njs_value_t *setval, njs_value_t *retval)
+{
+ char *p;
+ ngx_str_t *field;
+
+ p = njs_vm_external(vm, value);
+ if (p == NULL) {
+ njs_value_undefined_set(retval);
+ return NJS_DECLINED;
+ }
+
+ field = (ngx_str_t *) (p + njs_vm_prop_magic32(prop));
+
+ return njs_vm_value_string_set(vm, retval, field->data, field->len);
+}
+
+
+ngx_int_t
+ngx_js_integer(njs_vm_t *vm, njs_value_t *value, ngx_int_t *n)
+{
+ if (!njs_value_is_valid_number(value)) {
+ njs_vm_error(vm, "is not a number");
+ return NGX_ERROR;
+ }
+
+ *n = njs_value_number(value);
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
+ngx_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str)
+{
+ if (value != NULL && !njs_value_is_null_or_undefined(value)) {
+ if (njs_vm_value_to_string(vm, str, value) == NJS_ERROR) {
+ return NGX_ERROR;
+ }
+
+ } else {
+ str->start = NULL;
+ str->length = 0;
+ }
+
+ return NGX_OK;
+}
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_stream.h>
-
-#include <njs.h>
+#include "ngx_js.h"
typedef struct {
static void ngx_stream_js_timer_handler(ngx_event_t *ev);
static void ngx_stream_js_handle_event(ngx_stream_session_t *s,
njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs);
-static njs_int_t ngx_stream_js_string(njs_vm_t *vm, njs_value_t *value,
- njs_str_t *str);
static char *ngx_stream_js_include(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_int_t
ngx_stream_js_phase_handler(ngx_stream_session_t *s, ngx_str_t *name)
{
- njs_str_t fname, exception;
+ njs_str_t exception;
njs_int_t ret;
ngx_int_t rc;
- njs_function_t *func;
ngx_connection_t *c;
ngx_stream_js_ctx_t *ctx;
ctx = ngx_stream_get_module_ctx(s, ngx_stream_js_module);
if (!ctx->in_progress) {
- fname.start = name->data;
- fname.length = name->len;
-
- func = njs_vm_function(ctx->vm, &fname);
-
- if (func == NULL) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "js function \"%V\" not found", name);
- return NGX_ERROR;
- }
-
/*
* status is expected to be overriden by allow(), deny(), decline() or
* done() methods.
ctx->status = NGX_ERROR;
- ret = njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->args), 1);
- if (ret != NJS_OK) {
- goto exception;
+ rc = ngx_js_call(ctx->vm, name, &ctx->args[0], c->log);
+ if (rc == NGX_ERROR) {
+ return rc;
}
}
ngx_stream_js_body_filter(ngx_stream_session_t *s, ngx_chain_t *in,
ngx_uint_t from_upstream)
{
- njs_str_t name, exception;
+ njs_str_t exception;
njs_int_t ret;
ngx_int_t rc;
ngx_chain_t *out, *cl;
- njs_function_t *func;
ngx_connection_t *c;
ngx_stream_js_ctx_t *ctx;
ngx_stream_js_srv_conf_t *jscf;
ctx = ngx_stream_get_module_ctx(s, ngx_stream_js_module);
if (!ctx->filter) {
- name.start = jscf->filter.data;
- name.length = jscf->filter.len;
-
- func = njs_vm_function(ctx->vm, &name);
-
- if (func == NULL) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "js function \"%V\" not found", &jscf->filter);
- return NGX_ERROR;
- }
-
- ret = njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->args), 1);
- if (ret != NJS_OK) {
- goto exception;
+ rc = ngx_js_call(ctx->vm, &jscf->filter, &ctx->args[0], c->log);
+ if (rc == NGX_ERROR) {
+ return rc;
}
}
ngx_int_t rc;
njs_int_t pending;
- njs_str_t name, value, exception;
- njs_function_t *func;
+ njs_str_t value;
ngx_stream_js_ctx_t *ctx;
rc = ngx_stream_js_init_vm(s);
ctx = ngx_stream_get_module_ctx(s, ngx_stream_js_module);
- name.start = fname->data;
- name.length = fname->len;
-
- func = njs_vm_function(ctx->vm, &name);
- if (func == NULL) {
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "js function \"%V\" not found", fname);
- v->not_found = 1;
- return NGX_OK;
- }
-
pending = njs_vm_pending(ctx->vm);
- if (njs_vm_call(ctx->vm, func, njs_value_arg(&ctx->args), 1) != NJS_OK) {
- njs_vm_retval_string(ctx->vm, &exception);
-
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "js exception: %*s", exception.length, exception.start);
+ rc = ngx_js_call(ctx->vm, fname, &ctx->args[0], s->connection->log);
+ if (rc == NGX_ERROR) {
v->not_found = 1;
return NGX_OK;
}
- if (njs_vm_retval_string(ctx->vm, &value) != NJS_OK) {
+ if (!pending && rc == NGX_AGAIN) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "async operation inside \"%V\" variable handler", fname);
return NGX_ERROR;
}
- if (!pending && njs_vm_pending(ctx->vm)) {
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "async operation inside \"%V\" variable handler", fname);
+ if (njs_vm_retval_string(ctx->vm, &value) != NJS_OK) {
return NGX_ERROR;
}
code = njs_arg(args, nargs, 1);
if (!njs_value_is_undefined(code)) {
- if (!njs_value_is_valid_number(code)) {
- njs_vm_error(vm, "code is not a number");
+ if (ngx_js_integer(vm, code, &status) != NGX_OK) {
return NJS_ERROR;
}
- status = njs_value_number(code);
if (status < NGX_ABORT || status > NGX_STREAM_SERVICE_UNAVAILABLE) {
njs_vm_error(vm, "code is out of range");
return NJS_ERROR;
return NJS_ERROR;
}
- if (ngx_stream_js_string(vm, njs_arg(args, nargs, 1), &buffer) != NJS_OK) {
+ if (ngx_js_string(vm, njs_arg(args, nargs, 1), &buffer) != NGX_OK) {
njs_vm_error(vm, "failed to get buffer arg");
return NJS_ERROR;
}
return NJS_ERROR;
}
- rc = ngx_stream_js_string(vm, setval, &val);
- if (rc != NJS_OK) {
+ if (ngx_js_string(vm, setval, &val) != NGX_OK) {
return NJS_ERROR;
}
}
-static njs_int_t
-ngx_stream_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str)
-{
- if (!njs_value_is_null_or_undefined(value)) {
- if (njs_vm_value_to_string(vm, str, value) == NJS_ERROR) {
- return NJS_ERROR;
- }
-
- } else {
- str->start = NULL;
- str->length = 0;
- }
-
- return NJS_OK;
-}
-
-
static char *
ngx_stream_js_init_main_conf(ngx_conf_t *cf, void *conf)
{