[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