diff options
author | Anna Henningsen <anna@addaleax.net> | 2018-03-07 14:16:34 +0100 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2018-03-15 12:53:22 +0100 |
commit | 1ac14244763a7f87d51a517f0817eca82cbc86b6 (patch) | |
tree | cf0e01b521bec86d175c7f11d3ad679e7deca412 /src/node_http_parser.cc | |
parent | e136903700445f1d5f7555f22f69be189a14f682 (diff) | |
download | node-new-1ac14244763a7f87d51a517f0817eca82cbc86b6.tar.gz |
http: align parser with StreamBase interface changes
The `StreamBase` interface changed, so that `OnStreamRead()`
and `OnStreamAlloc()` are not guaranteed to be emitted in the
same tick any more.
This means that, while it isn’t causing any trouble right now,
we should not assume that it’s safe to return a static buffer
in the HTTP parser’s `OnStreamAlloc()` method.
PR-URL: https://github.com/nodejs/node/pull/18936
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'src/node_http_parser.cc')
-rw-r--r-- | src/node_http_parser.cc | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 207310f406..8ab13e0734 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -525,6 +525,14 @@ class Parser : public AsyncWrap, public StreamListener { static const size_t kAllocBufferSize = 64 * 1024; uv_buf_t OnStreamAlloc(size_t suggested_size) override { + // For most types of streams, OnStreamRead will be immediately after + // OnStreamAlloc, and will consume all data, so using a static buffer for + // reading is more efficient. For other streams, just use the default + // allocator, which uses Malloc(). + if (env()->http_parser_buffer_in_use()) + return StreamListener::OnStreamAlloc(suggested_size); + env()->set_http_parser_buffer_in_use(true); + if (env()->http_parser_buffer() == nullptr) env()->set_http_parser_buffer(new char[kAllocBufferSize]); @@ -534,6 +542,15 @@ class Parser : public AsyncWrap, public StreamListener { void OnStreamRead(ssize_t nread, const uv_buf_t& buf) override { HandleScope scope(env()->isolate()); + // Once we’re done here, either indicate that the HTTP parser buffer + // is free for re-use, or free() the data if it didn’t come from there + // in the first place. + OnScopeLeave on_scope_leave([&]() { + if (buf.base == env()->http_parser_buffer()) + env()->set_http_parser_buffer_in_use(false); + else + free(buf.base); + }); if (nread < 0) { PassReadErrorToPreviousListener(nread); |