@@ -82,6 +82,20 @@ inline bool IsOWS(char c) {
8282 return c == ' ' || c == ' \t ' ;
8383}
8484
85+ class BindingData : public BaseObject {
86+ public:
87+ BindingData (Environment* env, Local<Object> obj) : BaseObject(env, obj) {}
88+
89+ std::vector<char > parser_buffer;
90+ bool parser_buffer_in_use = false ;
91+
92+ void MemoryInfo (MemoryTracker* tracker) const override {
93+ tracker->TrackField (" parser_buffer" , parser_buffer);
94+ }
95+ SET_SELF_SIZE (BindingData)
96+ SET_MEMORY_INFO_NAME (BindingData)
97+ };
98+
8599// helper class for the Parser
86100struct StringPtr {
87101 StringPtr () {
@@ -164,10 +178,11 @@ struct StringPtr {
164178
165179class Parser : public AsyncWrap , public StreamListener {
166180 public:
167- Parser (Environment* env , Local<Object> wrap)
168- : AsyncWrap(env, wrap),
181+ Parser (BindingData* binding_data , Local<Object> wrap)
182+ : AsyncWrap(binding_data-> env () , wrap),
169183 current_buffer_len_(0 ),
170- current_buffer_data_(nullptr ) {
184+ current_buffer_data_(nullptr ),
185+ binding_data_(binding_data) {
171186 }
172187
173188
@@ -429,8 +444,8 @@ class Parser : public AsyncWrap, public StreamListener {
429444 }
430445
431446 static void New (const FunctionCallbackInfo<Value>& args) {
432- Environment* env = Environment::GetCurrent (args);
433- new Parser (env , args.This ());
447+ BindingData* binding_data = Unwrap<BindingData> (args. Data () );
448+ new Parser (binding_data , args.This ());
434449 }
435450
436451
@@ -605,14 +620,14 @@ class Parser : public AsyncWrap, public StreamListener {
605620 // For most types of streams, OnStreamRead will be immediately after
606621 // OnStreamAlloc, and will consume all data, so using a static buffer for
607622 // reading is more efficient. For other streams, just use Malloc() directly.
608- if (env ()-> http_parser_buffer_in_use () )
623+ if (binding_data_-> parser_buffer_in_use )
609624 return uv_buf_init (Malloc (suggested_size), suggested_size);
610- env ()-> set_http_parser_buffer_in_use ( true ) ;
625+ binding_data_-> parser_buffer_in_use = true ;
611626
612- if (env ()-> http_parser_buffer () == nullptr )
613- env ()-> set_http_parser_buffer ( new char [ kAllocBufferSize ] );
627+ if (binding_data_-> parser_buffer . empty () )
628+ binding_data_-> parser_buffer . resize ( kAllocBufferSize );
614629
615- return uv_buf_init (env ()-> http_parser_buffer (), kAllocBufferSize );
630+ return uv_buf_init (binding_data_-> parser_buffer . data (), kAllocBufferSize );
616631 }
617632
618633
@@ -622,8 +637,8 @@ class Parser : public AsyncWrap, public StreamListener {
622637 // is free for re-use, or free() the data if it didn’t come from there
623638 // in the first place.
624639 auto on_scope_leave = OnScopeLeave ([&]() {
625- if (buf.base == env ()-> http_parser_buffer ())
626- env ()-> set_http_parser_buffer_in_use ( false ) ;
640+ if (buf.base == binding_data_-> parser_buffer . data ())
641+ binding_data_-> parser_buffer_in_use = false ;
627642 else
628643 free (buf.base );
629644 });
@@ -863,6 +878,8 @@ class Parser : public AsyncWrap, public StreamListener {
863878 uint64_t headers_timeout_;
864879 uint64_t header_parsing_start_time_ = 0 ;
865880
881+ BaseObjectPtr<BindingData> binding_data_;
882+
866883 // These are helper functions for filling `http_parser_settings`, which turn
867884 // a member function of Parser into a C-style HTTP parser callback.
868885 template <typename Parser, Parser> struct Proxy ;
@@ -903,6 +920,9 @@ void InitializeHttpParser(Local<Object> target,
903920 Local<Context> context,
904921 void * priv) {
905922 Environment* env = Environment::GetCurrent (context);
923+ Environment::BindingScope<BindingData> binding_scope (env);
924+ if (!binding_scope) return ;
925+
906926 Local<FunctionTemplate> t = env->NewFunctionTemplate (Parser::New);
907927 t->InstanceTemplate ()->SetInternalFieldCount (Parser::kInternalFieldCount );
908928 t->SetClassName (FIXED_ONE_BYTE_STRING (env->isolate (), " HTTPParser" ));
0 commit comments