Dmitry Volyntsev [Wed, 24 Feb 2021 14:50:14 +0000 (14:50 +0000)]
Eliminating vm->main_index introduced in ea2ec4c3ed7d.
The vm->main_index was only needed for the disassembler in the
accumulative mode. It was used to prevent from disassembling the code
from the previous iterations in the CLI.
The same result can be achieved without introducing the VM level field.
Dmitry Volyntsev [Wed, 24 Feb 2021 14:48:20 +0000 (14:48 +0000)]
Decoupling parser structure from the main VM structure.
vm->parser is only needed during parsing phase, so it can be eliminated.
This improves dependencies tracking and readability.
As a side effect it fixes #372 issue on Github: previously, Function
constructor left VM context in inconsistent state if compilation failed.
The direct root cause was that a function object was created, but
because Function constructor ended prematurely the object was not fully
initialized. This is not a problem by itself because usually this
partially created object cannot be referenced. In the accumulative mode,
which is only enabled in CLI, vm->parser was used to store the references
to the variables from the previous iteration.
Dmitry Volyntsev [Wed, 10 Feb 2021 14:03:11 +0000 (14:03 +0000)]
Stream: fixed processing buffered data in body filter.
Previously, when data was proxied to upstream, it may be partially
written and is left in upstream connection buffer. Later, when
writing becomes possible again, the body filter is called but it
fails to call the next filter in the chain. This resulted in hanging
connection.
The fix is to take the buffered data in upstream connection into account.
Dmitry Volyntsev [Thu, 21 Jan 2021 18:44:58 +0000 (18:44 +0000)]
Modules: added ngx.fetch().
This is an initial implementation of Fetch API.
The following init options are supported:
body, headers, buffer_size (nginx specific), max_response_body_size
(nginx specific), method.
The following properties and methods of Response object are implemented:
arrayBuffer(), bodyUsed, json(), headers, ok, redirect, status, statusText,
text(), type, url.
The following properties and methods of Header object are implemented:
get(), getAll(), has().
Notable limitations: only http:// scheme is supported, redirects
are not handled.
Dmitry Volyntsev [Thu, 24 Dec 2020 18:35:18 +0000 (18:35 +0000)]
Refactored working with external prototypes.
Previously, njs_vm_external_prototype() returned the pointer to a
created prototype structure. Which were expected to be passed to
njs_vm_external_create() as is. The returned pointer is needed to be
stored somewhere by user code which complicates user code in cases when
many prototypes are created.
Instead, an index in the VM internal table is returned.
njs_vm_external_create() is changed accordingly. This simplifies
user code because the index is known at static time for most cases.
Dmitry Volyntsev [Fri, 27 Nov 2020 12:28:44 +0000 (12:28 +0000)]
HTTP: renaming reqBody,resBody to requestBuffer and responseBuffer.
In 434f20c29f4c, r.reqBody and r.resBody were introduced. Since quite
often request body and response body are valid strings, it is preferable
to leave both variants to avoid potential conversions.
To make distinction clearer, requestText and responseText aliases to
requestBody and responseBody were also added.
Previously, promise chain might not be invoked at all in some cases.
Specifically, this happened in HTTP module if promise chain did not start
with a r.subrequest() invocation.
The fix is to always process all pending promise events after the main module
function.
Dmitry Volyntsev [Wed, 18 Nov 2020 18:09:11 +0000 (18:09 +0000)]
HTTP: fixed promise subrequest() with error_page redirect.
Previously, promise callbacks for a subrequest were stored in a
subrequest context. This is incorrect because a subrequest content may
be destroyed (for example when error_page with redirect is enabled for a
subrequest location).
The fix is to store callbacks in the parent context.
The issue happened when the first eq symbol is located after the
separator, whereas it should be looked for only in the string segment
before the separator.
By default, promises should finish processing normally for .then(),
.catch(), .finally() and so on. The patch adds the ability to report
unhandled exception from promises to the user.
Fixed heap-buffer-overflow for RegExp.prototype[Symbol.replace].
Previously, RegExp.prototype[Symbol.replace] might overrun the boundaries
of the result of the custom "exec" method for a RegExp argument. The
issue occurred when the result object had zero length. The length is
used to create an array and the zero index was always written without
respect for the length resulting is heap-buffer-overflow.
njs_json_stringify_iterator() assumed, while stringifying flat arrays, that a
flat array will always remain flat. This is not the case for flat arrays with
values with custom getters which may modify the enclosing array upon
invocation.
This correctly fixes the issues addressed in 1405:9beb9ea093b5.
The initial fix wrongly assumed that the "value" pointer is still valid when
njs_is_fast_array(&state->value) is true and the pointer can be used for
the fast path. This is not the case when the array object is resized.
Moreover, the fast path branch may be completely eliminated because
JSON.parse() with the replacer function is relatively slow by itself.