This is great! Thank you! -- Sergey A. Osokin
On Sat, Feb 01, 2025 at 01:57:02AM +0000, nore...@nginx.com wrote: > details: > https://github.com/nginx/njs/commit/2d97e80486d7d2554e58cdaca4f2389b836600c8 > branches: master > commit: 2d97e80486d7d2554e58cdaca4f2389b836600c8 > user: Dmitry Volyntsev <xei...@nginx.com> > date: Tue, 28 Jan 2025 19:11:48 -0800 > description: > HTTP: reading r.requestText or r.requestBuffer from a temp file. > > Previously, an exception was thrown when accessing r.requestText or > r.requestBuffer if a client request body size exceeded > client_body_buffer_size. > > --- > nginx/ngx_http_js_module.c | 60 > +++++++++++++++++++++++++++++++++++++++------- > nginx/t/js_request_body.t | 29 +++++++++++++++++++--- > 2 files changed, 77 insertions(+), 12 deletions(-) > > diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c > index 04d06fb2..66cb97c0 100644 > --- a/nginx/ngx_http_js_module.c > +++ b/nginx/ngx_http_js_module.c > @@ -2916,6 +2916,7 @@ ngx_http_js_ext_get_request_body(njs_vm_t *vm, > njs_object_prop_t *prop, > { > u_char *p, *body; > size_t len; > + ssize_t n; > uint32_t buffer_type; > ngx_buf_t *buf; > njs_int_t ret; > @@ -2948,14 +2949,35 @@ ngx_http_js_ext_get_request_body(njs_vm_t *vm, > njs_object_prop_t *prop, > return NJS_DECLINED; > } > > - 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 (r->request_body->temp_file) { > + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, > + "http js reading request body from a temporary file"); > + > + if (buf == NULL || !buf->in_file) { > + njs_vm_internal_error(vm, "cannot find request body"); > + return NJS_ERROR; > + } > + > + len = buf->file_last - buf->file_pos; > + > + body = ngx_pnalloc(r->pool, len); > + if (body == NULL) { > + njs_vm_memory_error(vm); > + return NJS_ERROR; > + } > + > + n = ngx_read_file(buf->file, body, len, buf->file_pos); > + if (n != (ssize_t) len) { > + njs_vm_internal_error(vm, "failed to read request body"); > + return NJS_ERROR; > + } > + > + goto done; > + } > + > if (cl->next == NULL) { > len = buf->last - buf->pos; > body = buf->pos; > @@ -5259,6 +5281,7 @@ ngx_http_qjs_ext_request_body(JSContext *cx, > JSValueConst this_val, int type) > { > u_char *p, *data; > size_t len; > + ssize_t n; > JSValue body; > uint32_t buffer_type; > ngx_buf_t *buf; > @@ -5287,13 +5310,32 @@ ngx_http_qjs_ext_request_body(JSContext *cx, > JSValueConst this_val, int type) > return JS_UNDEFINED; > } > > - if (r->request_body->temp_file) { > - return JS_ThrowTypeError(cx, "request body is in a file"); > - } > - > cl = r->request_body->bufs; > buf = cl->buf; > > + if (r->request_body->temp_file) { > + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, > + "http js reading request body from a temporary file"); > + > + if (buf == NULL || !buf->in_file) { > + return JS_ThrowInternalError(cx, "cannot find body file"); > + } > + > + len = buf->file_last - buf->file_pos; > + > + data = ngx_pnalloc(r->pool, len); > + if (data == NULL) { > + return JS_ThrowOutOfMemory(cx); > + } > + > + n = ngx_read_file(buf->file, data, len, buf->file_pos); > + if (n != (ssize_t) len) { > + return JS_ThrowInternalError(cx, "failed to read request body"); > + } > + > + goto done; > + } > + > if (cl->next == NULL) { > len = buf->last - buf->pos; > data = buf->pos; > diff --git a/nginx/t/js_request_body.t b/nginx/t/js_request_body.t > index 360e4565..3980ea73 100644 > --- a/nginx/t/js_request_body.t > +++ b/nginx/t/js_request_body.t > @@ -47,11 +47,25 @@ http { > js_content test.body; > } > > + location /body_4k { > + client_body_buffer_size 4k; > + js_content test.body; > + } > + > location /in_file { > + js_content test.body; > + } > + > + location /in_file_on { > client_body_in_file_only on; > js_content test.body; > } > > + location /in_file_clean { > + client_body_in_file_only clean; > + js_content test.body; > + } > + > location /read_body_from_temp_file { > client_body_in_file_only clean; > js_content test.read_body_from_temp_file; > @@ -93,20 +107,29 @@ $t->write_file('test.js', <<EOF); > > EOF > > -$t->try_run('no njs request body')->plan(5); > +$t->try_run('no njs request body')->plan(9); > > > ############################################################################### > > like(http_post('/body'), qr/REQ-BODY/, 'request body'); > -like(http_post('/in_file'), qr/request body is in a file/, > - 'request body in file'); > +like(http_post('/in_file'), qr/REQ-BODY/, 'request body in a file'); > +like(http_post('/in_file_on'), qr/REQ-BODY/, 'request body in a file on'); > +like(http_post('/in_file_clean'), qr/REQ-BODY/, 'request body in a file > clean'); > like(http_post_big('/body'), qr/200.*^(1234567890){1024}$/ms, > 'request body big'); > +like(http_post_big('/body_4k'), qr/200.*^(1234567890){1024}$/ms, > + 'request body big with 4k buffer'); > like(http_post_big('/read_body_from_temp_file'), > qr/200.*^(1234567890){1024}$/ms, 'request body big from temp file'); > like(http_post('/request_body_cache'), > qr/requestText:string requestBuffer:buffer$/s, 'request body cache'); > > +$t->stop(); > + > +ok(index($t->read_file('error.log'), > + 'http js reading request body from a temporary file') > 0, > + 'http request body is in a file warning'); > + > > ############################################################################### > > sub http_post { > _______________________________________________ > nginx-devel mailing list > nginx-devel@nginx.org > https://mailman.nginx.org/mailman/listinfo/nginx-devel _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel