[njs] HTTP request body getter.
Dmitry Volyntsev
xeioex at nginx.com
Mon Apr 9 18:02:48 UTC 2018
details: http://hg.nginx.org/njs/rev/b7bfe96ce113
branches:
changeset: 497:b7bfe96ce113
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Mon Apr 09 21:02:11 2018 +0300
description:
HTTP request body getter.
Returns the client request body.
diffstat:
nginx/ngx_http_js_module.c | 102 +++++++++++++++++++++++++++++++++++++++++++-
njs/njs_vm.c | 7 +++
njs/njscript.h | 4 +
3 files changed, 109 insertions(+), 4 deletions(-)
diffs (192 lines):
diff -r 4466799a4231 -r b7bfe96ce113 nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c Mon Apr 09 21:02:10 2018 +0300
+++ b/nginx/ngx_http_js_module.c Mon Apr 09 21:02:11 2018 +0300
@@ -34,6 +34,7 @@ typedef struct {
njs_opaque_value_t args[2];
ngx_uint_t done;
ngx_int_t status;
+ njs_opaque_value_t request_body;
} ngx_http_js_ctx_t;
@@ -106,6 +107,8 @@ static njs_ret_t ngx_http_js_ext_get_htt
njs_value_t *value, void *obj, uintptr_t data);
static njs_ret_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm,
njs_value_t *value, void *obj, uintptr_t data);
+static njs_ret_t ngx_http_js_ext_get_request_body(njs_vm_t *vm,
+ njs_value_t *value, void *obj, uintptr_t data);
static njs_ret_t ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
static njs_ret_t ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj,
@@ -129,8 +132,8 @@ static ngx_int_t ngx_http_js_subrequest_
void *data, ngx_int_t rc);
static njs_ret_t ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_value_t *value,
void *obj, uintptr_t data);
-static njs_ret_t ngx_http_js_ext_get_body(njs_vm_t *vm, njs_value_t *value,
- void *obj, uintptr_t data);
+static njs_ret_t ngx_http_js_ext_get_reply_body(njs_vm_t *vm,
+ njs_value_t *value, void *obj, uintptr_t data);
static njs_host_event_t ngx_http_js_set_timer(njs_external_ptr_t external,
uint64_t delay, njs_vm_event_t vm_event);
@@ -358,6 +361,18 @@ static njs_external_t ngx_http_js_ext_r
NULL,
0 },
+ { nxt_string("body"),
+ NJS_EXTERN_PROPERTY,
+ NULL,
+ 0,
+ ngx_http_js_ext_get_request_body,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0 },
+
{ nxt_string("headers"),
NJS_EXTERN_OBJECT,
NULL,
@@ -546,7 +561,7 @@ static njs_external_t ngx_http_js_ext_r
NJS_EXTERN_PROPERTY,
NULL,
0,
- ngx_http_js_ext_get_body,
+ ngx_http_js_ext_get_reply_body,
NULL,
NULL,
NULL,
@@ -1436,6 +1451,85 @@ ngx_http_js_ext_get_remote_address(njs_v
static njs_ret_t
+ngx_http_js_ext_get_request_body(njs_vm_t *vm, njs_value_t *value, void *obj,
+ uintptr_t data)
+{
+ u_char *p, *body;
+ size_t len;
+ ngx_buf_t *buf;
+ njs_ret_t ret;
+ njs_value_t *request_body;
+ ngx_chain_t *cl;
+ ngx_http_js_ctx_t *ctx;
+ ngx_http_request_t *r;
+
+ r = (ngx_http_request_t *) obj;
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
+ request_body = (njs_value_t *) &ctx->request_body;
+
+ if (!njs_value_is_null(request_body)) {
+ njs_value_assign(value, request_body);
+ return NJS_OK;
+ }
+
+ if (r->request_body == NULL || r->request_body->bufs == NULL) {
+ njs_vm_error(vm, "request body is unavailable");
+ return NJS_ERROR;
+ }
+
+ if (r->request_body->temp_file) {
+ njs_vm_error(vm, "request body is in a file");
+ return NJS_ERROR;
+ }
+
+ cl = r->request_body->bufs;
+ buf = cl->buf;
+
+ if (cl->next == NULL) {
+ len = buf->last - buf->pos;
+ body = buf->pos;
+
+ goto done;
+ }
+
+ len = buf->last - buf->pos;
+ cl = cl->next;
+
+ for ( /* void */ ; cl; cl = cl->next) {
+ buf = cl->buf;
+ len += buf->last - buf->pos;
+ }
+
+ p = ngx_pnalloc(r->pool, len);
+ if (p == NULL) {
+ njs_vm_memory_error(vm);
+ return NJS_ERROR;
+ }
+
+ body = p;
+ cl = r->request_body->bufs;
+
+ for ( /* void */ ; cl; cl = cl->next) {
+ buf = cl->buf;
+ p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
+ }
+
+done:
+
+ ret = njs_string_create(vm, request_body, body, len, 0);
+
+ if (ret != NXT_OK) {
+ return NJS_ERROR;
+ }
+
+ njs_value_assign(value, request_body);
+
+ return NJS_OK;
+}
+
+
+static njs_ret_t
ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t *value, void *obj,
uintptr_t data)
{
@@ -1939,7 +2033,7 @@ ngx_http_js_ext_get_parent(njs_vm_t *vm,
static njs_ret_t
-ngx_http_js_ext_get_body(njs_vm_t *vm, njs_value_t *value, void *obj,
+ngx_http_js_ext_get_reply_body(njs_vm_t *vm, njs_value_t *value, void *obj,
uintptr_t data)
{
size_t len;
diff -r 4466799a4231 -r b7bfe96ce113 njs/njs_vm.c
--- a/njs/njs_vm.c Mon Apr 09 21:02:10 2018 +0300
+++ b/njs/njs_vm.c Mon Apr 09 21:02:11 2018 +0300
@@ -3730,6 +3730,13 @@ njs_value_function(njs_value_t *value)
nxt_noinline nxt_int_t
+njs_value_is_null(njs_value_t *value)
+{
+ return njs_is_null(value);
+}
+
+
+nxt_noinline nxt_int_t
njs_value_is_void(njs_value_t *value)
{
return njs_is_void(value);
diff -r 4466799a4231 -r b7bfe96ce113 njs/njscript.h
--- a/njs/njscript.h Mon Apr 09 21:02:10 2018 +0300
+++ b/njs/njscript.h Mon Apr 09 21:02:11 2018 +0300
@@ -29,6 +29,9 @@ typedef struct {
#define njs_argument(args, n) \
(njs_value_t *) ((u_char *) args + n * 16)
+#define njs_value_assign(dst, src) \
+ *((njs_opaque_value_t *) dst) = *((njs_opaque_value_t *) src);
+
#define njs_vm_error(vm, fmt, ...) \
njs_value_error_set(vm, njs_vm_retval(vm), fmt, ##__VA_ARGS__)
@@ -193,6 +196,7 @@ NXT_EXPORT double njs_value_number(njs_v
NXT_EXPORT void *njs_value_data(njs_value_t *value);
NXT_EXPORT njs_function_t *njs_value_function(njs_value_t *value);
+NXT_EXPORT nxt_int_t njs_value_is_null(njs_value_t *value);
NXT_EXPORT nxt_int_t njs_value_is_void(njs_value_t *value);
NXT_EXPORT nxt_int_t njs_value_is_boolean(njs_value_t *value);
NXT_EXPORT nxt_int_t njs_value_is_number(njs_value_t *value);
More information about the nginx-devel
mailing list