@@ -1117,36 +1117,6 @@ inline int Http2Session::OnNghttpError(nghttp2_session* handle,
11171117 return 0 ;
11181118}
11191119
1120- // Once all of the DATA frames for a Stream have been sent, the GetTrailers
1121- // method calls out to JavaScript to fetch the trailing headers that need
1122- // to be sent.
1123- inline void Http2Session::GetTrailers (Http2Stream* stream, uint32_t * flags) {
1124- if (!stream->IsDestroyed () && stream->HasTrailers ()) {
1125- Http2Stream::SubmitTrailers submit_trailers{this , stream, flags};
1126- stream->OnTrailers (submit_trailers);
1127- }
1128- }
1129-
1130-
1131- Http2Stream::SubmitTrailers::SubmitTrailers (
1132- Http2Session* session,
1133- Http2Stream* stream,
1134- uint32_t * flags)
1135- : session_(session), stream_(stream), flags_(flags) { }
1136-
1137-
1138- inline void Http2Stream::SubmitTrailers::Submit (nghttp2_nv* trailers,
1139- size_t length) const {
1140- Http2Scope h2scope (session_);
1141- if (length == 0 )
1142- return ;
1143- DEBUG_HTTP2SESSION2 (session_, " sending trailers for stream %d, count: %d" ,
1144- stream_->id (), length);
1145- *flags_ |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
1146- CHECK_EQ (
1147- nghttp2_submit_trailer (**session_, stream_->id (), trailers, length), 0 );
1148- }
1149-
11501120
11511121// Called by OnFrameReceived to notify JavaScript land that a complete
11521122// HEADERS frame has been received and processed. This method converts the
@@ -1808,29 +1778,6 @@ nghttp2_stream* Http2Stream::operator*() {
18081778}
18091779
18101780
1811- // Calls out to JavaScript land to fetch the actual trailer headers to send
1812- // for this stream.
1813- void Http2Stream::OnTrailers (const SubmitTrailers& submit_trailers) {
1814- DEBUG_HTTP2STREAM (this , " prompting for trailers" );
1815- CHECK (!this ->IsDestroyed ());
1816- Isolate* isolate = env ()->isolate ();
1817- HandleScope scope (isolate);
1818- Local<Context> context = env ()->context ();
1819- Context::Scope context_scope (context);
1820-
1821- Local<Value> ret =
1822- MakeCallback (env ()->ontrailers_string (), 0 , nullptr ).ToLocalChecked ();
1823- if (!ret.IsEmpty () && !IsDestroyed ()) {
1824- if (ret->IsArray ()) {
1825- Local<Array> headers = ret.As <Array>();
1826- if (headers->Length () > 0 ) {
1827- Headers trailers (isolate, context, headers);
1828- submit_trailers.Submit (*trailers, trailers.length ());
1829- }
1830- }
1831- }
1832- }
1833-
18341781inline void Http2Stream::Close (int32_t code) {
18351782 CHECK (!this ->IsDestroyed ());
18361783 flags_ |= NGHTTP2_STREAM_FLAG_CLOSED;
@@ -1952,6 +1899,26 @@ inline int Http2Stream::SubmitInfo(nghttp2_nv* nva, size_t len) {
19521899 return ret;
19531900}
19541901
1902+ void Http2Stream::OnTrailers () {
1903+ DEBUG_HTTP2STREAM (this , " let javascript know we are ready for trailers" );
1904+ CHECK (!this ->IsDestroyed ());
1905+ Isolate* isolate = env ()->isolate ();
1906+ HandleScope scope (isolate);
1907+ Local<Context> context = env ()->context ();
1908+ Context::Scope context_scope (context);
1909+ MakeCallback (env ()->ontrailers_string (), 0 , nullptr );
1910+ }
1911+
1912+ // Submit informational headers for a stream.
1913+ int Http2Stream::SubmitTrailers (nghttp2_nv* nva, size_t len) {
1914+ CHECK (!this ->IsDestroyed ());
1915+ Http2Scope h2scope (this );
1916+ DEBUG_HTTP2STREAM2 (this , " sending %d trailers" , len);
1917+ int ret = nghttp2_submit_trailer (**session_, id_, nva, len);
1918+ CHECK_NE (ret, NGHTTP2_ERR_NOMEM);
1919+ return ret;
1920+ }
1921+
19551922// Submit a PRIORITY frame to the connected peer.
19561923inline int Http2Stream::SubmitPriority (nghttp2_priority_spec* prispec,
19571924 bool silent) {
@@ -2184,13 +2151,6 @@ ssize_t Http2Stream::Provider::FD::OnRead(nghttp2_session* handle,
21842151 if (static_cast <size_t >(numchars) < length || length <= 0 ) {
21852152 DEBUG_HTTP2SESSION2 (session, " no more data for stream %d" , id);
21862153 *flags |= NGHTTP2_DATA_FLAG_EOF;
2187- session->GetTrailers (stream, flags);
2188- // If the stream or session gets destroyed during the GetTrailers
2189- // callback, check that here and close down the stream
2190- if (stream->IsDestroyed ())
2191- return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
2192- if (session->IsDestroyed ())
2193- return NGHTTP2_ERR_CALLBACK_FAILURE;
21942154 }
21952155
21962156 stream->statistics_ .sent_bytes += numchars;
@@ -2258,13 +2218,10 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle,
22582218 if (stream->queue_ .empty () && !stream->IsWritable ()) {
22592219 DEBUG_HTTP2SESSION2 (session, " no more data for stream %d" , id);
22602220 *flags |= NGHTTP2_DATA_FLAG_EOF;
2261- session->GetTrailers (stream, flags);
2262- // If the stream or session gets destroyed during the GetTrailers
2263- // callback, check that here and close down the stream
2264- if (stream->IsDestroyed ())
2265- return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
2266- if (session->IsDestroyed ())
2267- return NGHTTP2_ERR_CALLBACK_FAILURE;
2221+ if (stream->HasTrailers ()) {
2222+ *flags |= NGHTTP2_DATA_FLAG_NO_END_STREAM;
2223+ stream->OnTrailers ();
2224+ }
22682225 }
22692226
22702227 stream->statistics_ .sent_bytes += amount;
@@ -2574,6 +2531,21 @@ void Http2Stream::Info(const FunctionCallbackInfo<Value>& args) {
25742531 headers->Length ());
25752532}
25762533
2534+ // Submits trailing headers on the Http2Stream
2535+ void Http2Stream::Trailers (const FunctionCallbackInfo<Value>& args) {
2536+ Environment* env = Environment::GetCurrent (args);
2537+ Local<Context> context = env->context ();
2538+ Isolate* isolate = env->isolate ();
2539+ Http2Stream* stream;
2540+ ASSIGN_OR_RETURN_UNWRAP (&stream, args.Holder ());
2541+
2542+ Local<Array> headers = args[0 ].As <Array>();
2543+
2544+ Headers list (isolate, context, headers);
2545+ args.GetReturnValue ().Set (stream->SubmitTrailers (*list, list.length ()));
2546+ DEBUG_HTTP2STREAM2 (stream, " %d trailing headers sent" , headers->Length ());
2547+ }
2548+
25772549// Grab the numeric id of the Http2Stream
25782550void Http2Stream::GetID (const FunctionCallbackInfo<Value>& args) {
25792551 Http2Stream* stream;
@@ -2921,6 +2893,7 @@ void Initialize(Local<Object> target,
29212893 env->SetProtoMethod (stream, " priority" , Http2Stream::Priority);
29222894 env->SetProtoMethod (stream, " pushPromise" , Http2Stream::PushPromise);
29232895 env->SetProtoMethod (stream, " info" , Http2Stream::Info);
2896+ env->SetProtoMethod (stream, " trailers" , Http2Stream::Trailers);
29242897 env->SetProtoMethod (stream, " respondFD" , Http2Stream::RespondFD);
29252898 env->SetProtoMethod (stream, " respond" , Http2Stream::Respond);
29262899 env->SetProtoMethod (stream, " rstStream" , Http2Stream::RstStream);
0 commit comments