@@ -122,47 +122,55 @@ Http3Application::Http3Application(
122122int64_t Http3Application::CreateAndBindPushStream (int64_t push_id) {
123123 CHECK (session ()->is_server ());
124124 int64_t stream_id;
125- if (!session ()->OpenUnidirectionalStream (&stream_id))
126- return 0 ;
127- return nghttp3_conn_bind_push_stream (
128- connection (),
129- push_id,
130- stream_id) == 0 ? stream_id : 0 ;
125+ return session ()->OpenUnidirectionalStream (&stream_id) &&
126+ nghttp3_conn_bind_push_stream (connection (), push_id, stream_id) == 0
127+ ? stream_id : 0 ;
131128}
132129
133- bool Http3Application::SubmitPushPromise (
130+ Http3Application::PushInfo Http3Application::SubmitPushPromise (
134131 int64_t id,
135- int64_t * push_id,
136- int64_t * stream_id,
137132 const Http3Headers& headers) {
138133 // Successfully creating the push promise and opening the
139134 // fulfillment stream will queue nghttp3 up to send data.
140135 // Creating the SendSessionScope here ensures that when
141136 // SubmitPush exits, SendPendingData will be called if
142137 // we are not within the context of an ngtcp2 callback.
143138 QuicSession::SendSessionScope send_scope (session ());
139+ PushInfo info{};
144140
145141 Debug (
146- session (),
147- " Submitting %d push promise headers" ,
148- headers.length ());
142+ session (),
143+ " Submitting %d push promise headers" ,
144+ headers.length ());
149145 if (nghttp3_conn_submit_push_promise (
150146 connection (),
151- push_id,
147+ &info. push_id ,
152148 id,
153149 headers.data (),
154- headers.length ()) != 0 ) {
155- return false ;
150+ headers.length ()) == 0 ) {
151+ // Once we've successfully submitted the push promise and have
152+ // a push id assigned, we create the push fulfillment stream.
153+ info.stream_id = CreateAndBindPushStream (info.push_id );
154+ Debug (
155+ session (),
156+ " Push stream created and bound. Push ID: %" PRId64
157+ " . Stream ID: %" PRId64,
158+ info.push_id ,
159+ info.stream_id );
156160 }
157- // Once we've successfully submitting the push promise and have
158- // a push id assigned, we create the push fulfillment stream.
159- *stream_id = CreateAndBindPushStream (*push_id);
160- return *stream_id != 0 ; // push stream can never use stream id 0
161+ return info;
161162}
162163
164+ // Information headers are 1xx status blocks that are transmitted
165+ // before the initial response headers. They should only ever be
166+ // transmitted by the server, however, other than checking that
167+ // this QuicSession is a server, we do not perform any additional
168+ // verification.
163169bool Http3Application::SubmitInformation (
164170 int64_t id,
165171 const Http3Headers& headers) {
172+ if (!session ()->is_server ())
173+ return false ;
166174 QuicSession::SendSessionScope send_scope (session ());
167175 Debug (
168176 session (),
@@ -176,6 +184,8 @@ bool Http3Application::SubmitInformation(
176184 headers.length ()) == 0 ;
177185}
178186
187+ // Trailers are headers that are transmitted after the HTTP message
188+ // payload and may be sent by either server or client.
179189bool Http3Application::SubmitTrailers (
180190 int64_t id,
181191 const Http3Headers& headers) {
@@ -232,24 +242,20 @@ bool Http3Application::SubmitHeaders(
232242// The headers block passed to the submit push contains the assumed
233243// *request* headers. The response headers are provided using the
234244// SubmitHeaders() function on the created QuicStream.
245+ //
246+ // A push can only be submitted on the server-side.
235247BaseObjectPtr<QuicStream> Http3Application::SubmitPush (
236248 int64_t id,
237249 Local<Array> headers) {
238- // If the QuicSession is not a server session, return false
239- // immediately. Push streams cannot be sent by an HTTP/3 client.
240- if (!session ()->is_server ())
241- return {};
242250
243- Http3Headers nva (env (), headers);
244- int64_t push_id;
245- int64_t stream_id;
251+ Http3Application::PushInfo info{};
252+
253+ if (session ()->is_server ())
254+ info = SubmitPushPromise (id, Http3Headers (env (), headers));
246255
247- // There are several reasons why push may fail. We currently handle
248- // them all the same. Later we might want to differentiate when the
249- // return value is NGHTTP3_ERR_PUSH_ID_BLOCKED.
250- return SubmitPushPromise (id, &push_id, &stream_id, nva) ?
251- QuicStream::New (session (), stream_id, push_id) :
252- BaseObjectPtr<QuicStream>();
256+ return info.stream_id != 0
257+ ? QuicStream::New (session (), info.stream_id , info.push_id )
258+ : BaseObjectPtr<QuicStream>();
253259}
254260
255261// Submit informational headers (response headers that use a 1xx
@@ -259,10 +265,7 @@ BaseObjectPtr<QuicStream> Http3Application::SubmitPush(
259265bool Http3Application::SubmitInformation (
260266 int64_t stream_id,
261267 Local<Array> headers) {
262- if (!session ()->is_server ())
263- return false ;
264- Http3Headers nva (session ()->env (), headers);
265- return SubmitInformation (stream_id, nva);
268+ return SubmitInformation (stream_id, Http3Headers (session ()->env (), headers));
266269}
267270
268271// For client sessions, submits request headers. For server sessions,
@@ -271,16 +274,17 @@ bool Http3Application::SubmitHeaders(
271274 int64_t stream_id,
272275 Local<Array> headers,
273276 uint32_t flags) {
274- Http3Headers nva (session ()->env (), headers);
275- return SubmitHeaders (stream_id, nva, flags);
277+ return SubmitHeaders (
278+ stream_id,
279+ Http3Headers (session ()->env (), headers),
280+ flags);
276281}
277282
278283// Submits trailing headers for the HTTP/3 request or response.
279284bool Http3Application::SubmitTrailers (
280285 int64_t stream_id,
281286 Local<Array> headers) {
282- Http3Headers nva (session ()->env (), headers);
283- return SubmitTrailers (stream_id, nva);
287+ return SubmitTrailers (stream_id, Http3Headers (session ()->env (), headers));
284288}
285289
286290void Http3Application::CheckAllocatedSize (size_t previous_size) const {
@@ -387,13 +391,12 @@ bool Http3Application::Initialize() {
387391 params.initial_max_streams_bidi );
388392 }
389393
390- if (! CreateAndBindControlStream () ||
391- ! CreateAndBindQPackStreams ()) {
392- return false ;
394+ if (CreateAndBindControlStream () && CreateAndBindQPackStreams ()) {
395+ set_init_done ();
396+ return true ;
393397 }
394398
395- set_init_done ();
396- return true ;
399+ return false ;
397400}
398401
399402// All HTTP/3 control, header, and stream data arrives as QUIC stream data.
0 commit comments