@@ -1117,36 +1117,6 @@ inline int Http2Session::OnNghttpError(nghttp2_session* handle,
1117
1117
return 0 ;
1118
1118
}
1119
1119
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
-
1150
1120
1151
1121
// Called by OnFrameReceived to notify JavaScript land that a complete
1152
1122
// HEADERS frame has been received and processed. This method converts the
@@ -1808,29 +1778,6 @@ nghttp2_stream* Http2Stream::operator*() {
1808
1778
}
1809
1779
1810
1780
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
-
1834
1781
inline void Http2Stream::Close (int32_t code) {
1835
1782
CHECK (!this ->IsDestroyed ());
1836
1783
flags_ |= NGHTTP2_STREAM_FLAG_CLOSED;
@@ -1952,6 +1899,26 @@ inline int Http2Stream::SubmitInfo(nghttp2_nv* nva, size_t len) {
1952
1899
return ret;
1953
1900
}
1954
1901
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
+
1955
1922
// Submit a PRIORITY frame to the connected peer.
1956
1923
inline int Http2Stream::SubmitPriority (nghttp2_priority_spec* prispec,
1957
1924
bool silent) {
@@ -2184,13 +2151,6 @@ ssize_t Http2Stream::Provider::FD::OnRead(nghttp2_session* handle,
2184
2151
if (static_cast <size_t >(numchars) < length || length <= 0 ) {
2185
2152
DEBUG_HTTP2SESSION2 (session, " no more data for stream %d" , id);
2186
2153
*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;
2194
2154
}
2195
2155
2196
2156
stream->statistics_ .sent_bytes += numchars;
@@ -2258,13 +2218,10 @@ ssize_t Http2Stream::Provider::Stream::OnRead(nghttp2_session* handle,
2258
2218
if (stream->queue_ .empty () && !stream->IsWritable ()) {
2259
2219
DEBUG_HTTP2SESSION2 (session, " no more data for stream %d" , id);
2260
2220
*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
+ }
2268
2225
}
2269
2226
2270
2227
stream->statistics_ .sent_bytes += amount;
@@ -2574,6 +2531,21 @@ void Http2Stream::Info(const FunctionCallbackInfo<Value>& args) {
2574
2531
headers->Length ());
2575
2532
}
2576
2533
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
+
2577
2549
// Grab the numeric id of the Http2Stream
2578
2550
void Http2Stream::GetID (const FunctionCallbackInfo<Value>& args) {
2579
2551
Http2Stream* stream;
@@ -2921,6 +2893,7 @@ void Initialize(Local<Object> target,
2921
2893
env->SetProtoMethod (stream, " priority" , Http2Stream::Priority);
2922
2894
env->SetProtoMethod (stream, " pushPromise" , Http2Stream::PushPromise);
2923
2895
env->SetProtoMethod (stream, " info" , Http2Stream::Info);
2896
+ env->SetProtoMethod (stream, " trailers" , Http2Stream::Trailers);
2924
2897
env->SetProtoMethod (stream, " respondFD" , Http2Stream::RespondFD);
2925
2898
env->SetProtoMethod (stream, " respond" , Http2Stream::Respond);
2926
2899
env->SetProtoMethod (stream, " rstStream" , Http2Stream::RstStream);
0 commit comments