1818#include " sessionticket.h"
1919
2020namespace node ::quic {
21- namespace {
2221
2322struct Http3HeadersTraits {
2423 typedef nghttp3_nv nv_t ;
@@ -116,13 +115,15 @@ class Http3Application final : public Session::Application {
116115 return CreateAndBindControlStreams ();
117116 }
118117
119- bool ReceiveStreamData (Stream* stream ,
118+ bool ReceiveStreamData (int64_t stream_id ,
120119 const uint8_t * data,
121120 size_t datalen,
122- Stream::ReceiveDataFlags flags) override {
121+ const Stream::ReceiveDataFlags& flags,
122+ void * unused) override {
123123 Debug (&session (), " HTTP/3 application received %zu bytes of data" , datalen);
124+
124125 ssize_t nread = nghttp3_conn_read_stream (
125- *this , stream-> id () , data, datalen, flags.fin ? 1 : 0 );
126+ *this , stream_id , data, datalen, flags.fin ? 1 : 0 );
126127
127128 if (nread < 0 ) {
128129 Debug (&session (),
@@ -134,7 +135,7 @@ class Http3Application final : public Session::Application {
134135 Debug (&session (),
135136 " Extending stream and connection offset by %zd bytes" ,
136137 nread);
137- session ().ExtendStreamOffset (stream-> id () , nread);
138+ session ().ExtendStreamOffset (stream_id , nread);
138139 session ().ExtendOffset (nread);
139140
140141 return true ;
@@ -614,11 +615,13 @@ class Http3Application final : public Session::Application {
614615 }
615616
616617#define NGHTTP3_CALLBACK_SCOPE (name ) \
617- auto name = From(conn, conn_user_data); \
618- if (name->is_destroyed ()) [[unlikely]] { \
618+ auto ptr = From(conn, conn_user_data); \
619+ CHECK_NOT_NULL (ptr); \
620+ auto & name = *ptr; \
621+ if (name.is_destroyed()) [[unlikely]] { \
619622 return NGHTTP3_ERR_CALLBACK_FAILURE; \
620623 } \
621- NgHttp3CallbackScope scope (name-> env ());
624+ NgHttp3CallbackScope scope (name. env());
622625
623626 static nghttp3_ssize on_read_data_callback (nghttp3_conn* conn,
624627 int64_t stream_id,
@@ -638,7 +641,7 @@ class Http3Application final : public Session::Application {
638641 NGHTTP3_CALLBACK_SCOPE (app);
639642 auto stream = From (stream_id, stream_user_data);
640643 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
641- app-> AcknowledgeStreamData (stream, static_cast <size_t >(datalen));
644+ app. AcknowledgeStreamData (stream, static_cast <size_t >(datalen));
642645 return NGTCP2_SUCCESS;
643646 }
644647
@@ -650,7 +653,7 @@ class Http3Application final : public Session::Application {
650653 NGHTTP3_CALLBACK_SCOPE (app);
651654 auto stream = From (stream_id, stream_user_data);
652655 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
653- app-> OnStreamClose (stream, app_error_code);
656+ app. OnStreamClose (stream, app_error_code);
654657 return NGTCP2_SUCCESS;
655658 }
656659
@@ -661,10 +664,31 @@ class Http3Application final : public Session::Application {
661664 void * conn_user_data,
662665 void * stream_user_data) {
663666 NGHTTP3_CALLBACK_SCOPE (app);
664- auto stream = From (stream_id, stream_user_data);
665- if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
666- app->OnReceiveData (stream,
667- nghttp3_vec{const_cast <uint8_t *>(data), datalen});
667+ auto & session = app.session ();
668+ BaseObjectPtr<Stream> stream;
669+ if (stream_user_data == nullptr ) {
670+ // The stream does not exist yet! Create it
671+ stream = session.CreateStream (stream_id);
672+ if (!stream) {
673+ Debug (&session, " HTTP3 application failed to create new stream" );
674+ return NGHTTP3_ERR_CALLBACK_FAILURE;
675+ }
676+ // Memoize the stream instance so we can look it up next time.
677+ nghttp3_conn_set_stream_user_data (conn, stream_id, stream.get ());
678+ session.EmitStream (stream);
679+ } else {
680+ stream = BaseObjectPtr<Stream>(From (stream_id, stream_user_data));
681+ if (!stream) {
682+ Debug (&session,
683+ " HTTP3 application failed to get existing stream "
684+ " from user data" );
685+ return NGHTTP3_ERR_CALLBACK_FAILURE;
686+ }
687+ }
688+
689+ DCHECK (stream);
690+ app.OnReceiveData (stream.get (),
691+ nghttp3_vec{const_cast <uint8_t *>(data), datalen});
668692 return NGTCP2_SUCCESS;
669693 }
670694
@@ -676,7 +700,7 @@ class Http3Application final : public Session::Application {
676700 NGHTTP3_CALLBACK_SCOPE (app);
677701 auto stream = From (stream_id, stream_user_data);
678702 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
679- app-> OnDeferredConsume (stream, consumed);
703+ app. OnDeferredConsume (stream, consumed);
680704 return NGTCP2_SUCCESS;
681705 }
682706
@@ -687,7 +711,7 @@ class Http3Application final : public Session::Application {
687711 NGHTTP3_CALLBACK_SCOPE (app);
688712 auto stream = From (stream_id, stream_user_data);
689713 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
690- app-> OnBeginHeaders (stream);
714+ app. OnBeginHeaders (stream);
691715 return NGTCP2_SUCCESS;
692716 }
693717
@@ -703,8 +727,8 @@ class Http3Application final : public Session::Application {
703727 auto stream = From (stream_id, stream_user_data);
704728 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
705729 if (Http3Header::IsZeroLength (token, name, value)) return NGTCP2_SUCCESS;
706- app-> OnReceiveHeader (stream,
707- Http3Header (app-> env (), token, name, value, flags));
730+ app. OnReceiveHeader (stream,
731+ Http3Header (app. env (), token, name, value, flags));
708732 return NGTCP2_SUCCESS;
709733 }
710734
@@ -716,7 +740,7 @@ class Http3Application final : public Session::Application {
716740 NGHTTP3_CALLBACK_SCOPE (app);
717741 auto stream = From (stream_id, stream_user_data);
718742 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
719- app-> OnEndHeaders (stream, fin);
743+ app. OnEndHeaders (stream, fin);
720744 return NGTCP2_SUCCESS;
721745 }
722746
@@ -727,7 +751,7 @@ class Http3Application final : public Session::Application {
727751 NGHTTP3_CALLBACK_SCOPE (app);
728752 auto stream = From (stream_id, stream_user_data);
729753 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
730- app-> OnBeginTrailers (stream);
754+ app. OnBeginTrailers (stream);
731755 return NGTCP2_SUCCESS;
732756 }
733757
@@ -743,8 +767,8 @@ class Http3Application final : public Session::Application {
743767 auto stream = From (stream_id, stream_user_data);
744768 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
745769 if (Http3Header::IsZeroLength (token, name, value)) return NGTCP2_SUCCESS;
746- app-> OnReceiveTrailer (stream,
747- Http3Header (app-> env (), token, name, value, flags));
770+ app. OnReceiveTrailer (stream,
771+ Http3Header (app. env (), token, name, value, flags));
748772 return NGTCP2_SUCCESS;
749773 }
750774
@@ -756,7 +780,7 @@ class Http3Application final : public Session::Application {
756780 NGHTTP3_CALLBACK_SCOPE (app);
757781 auto stream = From (stream_id, stream_user_data);
758782 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
759- app-> OnEndTrailers (stream, fin);
783+ app. OnEndTrailers (stream, fin);
760784 return NGTCP2_SUCCESS;
761785 }
762786
@@ -767,7 +791,7 @@ class Http3Application final : public Session::Application {
767791 NGHTTP3_CALLBACK_SCOPE (app);
768792 auto stream = From (stream_id, stream_user_data);
769793 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
770- app-> OnEndStream (stream);
794+ app. OnEndStream (stream);
771795 return NGTCP2_SUCCESS;
772796 }
773797
@@ -779,7 +803,7 @@ class Http3Application final : public Session::Application {
779803 NGHTTP3_CALLBACK_SCOPE (app);
780804 auto stream = From (stream_id, stream_user_data);
781805 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
782- app-> OnStopSending (stream, app_error_code);
806+ app. OnStopSending (stream, app_error_code);
783807 return NGTCP2_SUCCESS;
784808 }
785809
@@ -791,21 +815,21 @@ class Http3Application final : public Session::Application {
791815 NGHTTP3_CALLBACK_SCOPE (app);
792816 auto stream = From (stream_id, stream_user_data);
793817 if (stream == nullptr ) return NGHTTP3_ERR_CALLBACK_FAILURE;
794- app-> OnResetStream (stream, app_error_code);
818+ app. OnResetStream (stream, app_error_code);
795819 return NGTCP2_SUCCESS;
796820 }
797821
798822 static int on_shutdown (nghttp3_conn* conn, int64_t id, void * conn_user_data) {
799823 NGHTTP3_CALLBACK_SCOPE (app);
800- app-> OnShutdown ();
824+ app. OnShutdown ();
801825 return NGTCP2_SUCCESS;
802826 }
803827
804828 static int on_receive_settings (nghttp3_conn* conn,
805829 const nghttp3_settings* settings,
806830 void * conn_user_data) {
807831 NGHTTP3_CALLBACK_SCOPE (app);
808- app-> OnReceiveSettings (settings);
832+ app. OnReceiveSettings (settings);
809833 return NGTCP2_SUCCESS;
810834 }
811835
@@ -825,7 +849,6 @@ class Http3Application final : public Session::Application {
825849 on_shutdown,
826850 on_receive_settings};
827851};
828- } // namespace
829852
830853std::unique_ptr<Session::Application> createHttp3Application (
831854 Session* session, const Session::Application_Options& options) {
0 commit comments