From: Dmitry Volyntsev Date: Thu, 21 Jul 2022 00:49:00 +0000 (-0700) Subject: Modules: fixed reading response body in fetch API. X-Git-Tag: 0.7.7~25 X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=de96bdedc507480d20b357c695a82a46adc4e1e2;p=njs.git Modules: fixed reading response body in fetch API. Previously, the response body was ignored if the Content-Length was missing. This closes #557 issue on Github. --- diff --git a/nginx/ngx_js_fetch.c b/nginx/ngx_js_fetch.c index a01b5895..3fb79285 100644 --- a/nginx/ngx_js_fetch.c +++ b/nginx/ngx_js_fetch.c @@ -623,6 +623,8 @@ ngx_js_http_alloc(njs_vm_t *vm, ngx_pool_t *pool, ngx_log_t *log) http->timeout = 10000; + http->http_parse.content_length_n = -1; + ret = njs_vm_promise_create(vm, njs_value_arg(&http->promise), njs_value_arg(&http->promise_callbacks)); if (ret != NJS_OK) { @@ -1388,7 +1390,7 @@ ngx_js_http_process_headers(ngx_js_http_t *http) static ngx_int_t ngx_js_http_process_body(ngx_js_http_t *http) { - ssize_t size, need; + ssize_t size, chsize, need; ngx_int_t rc; njs_int_t ret; ngx_buf_t *b; @@ -1403,7 +1405,16 @@ ngx_js_http_process_body(ngx_js_http_t *http) return NGX_ERROR; } - if (size == http->http_parse.content_length_n) { + if (http->http_parse.chunked + && http->http_parse.content_length_n == -1) + { + ngx_js_http_error(http, 0, "invalid fetch chunked response"); + return NGX_ERROR; + } + + if (http->http_parse.content_length_n == -1 + || size == http->http_parse.content_length_n) + { ret = njs_vm_external_create(http->vm, njs_value_arg(&http->reply), ngx_http_js_fetch_proto_id, http, 0); if (ret != NJS_OK) { @@ -1415,13 +1426,6 @@ ngx_js_http_process_body(ngx_js_http_t *http) return NGX_DONE; } - if (http->http_parse.chunked - && http->http_parse.content_length_n == 0) - { - ngx_js_http_error(http, 0, "invalid fetch chunked response"); - return NGX_ERROR; - } - if (size < http->http_parse.content_length_n) { return NGX_AGAIN; } @@ -1454,17 +1458,28 @@ ngx_js_http_process_body(ngx_js_http_t *http) b->pos = http->http_chunk_parse.pos; } else { - need = http->http_parse.content_length_n - njs_chb_size(&http->chain); - size = ngx_min(need, b->last - b->pos); + size = njs_chb_size(&http->chain); - if (size > 0) { - njs_chb_append(&http->chain, b->pos, size); - b->pos += size; - rc = NGX_AGAIN; + if (http->http_parse.content_length_n == -1) { + need = http->max_response_body_size - size; } else { - rc = NGX_DONE; + need = http->http_parse.content_length_n - size; } + + chsize = ngx_min(need, b->last - b->pos); + + if (size + chsize > http->max_response_body_size) { + ngx_js_http_error(http, 0, "fetch response body is too large"); + return NGX_ERROR; + } + + if (chsize > 0) { + njs_chb_append(&http->chain, b->pos, chsize); + b->pos += chsize; + } + + rc = (need > chsize) ? NGX_AGAIN : NGX_DONE; } if (b->pos == b->end) {