@@ -514,8 +514,12 @@ class Http3ApplicationImpl final : public Session::Application {
514514 flags.fin ,
515515 flags.early );
516516
517+ uint64_t ts = session ().rx_packet_ts ();
518+ if (ts == 0 ) [[unlikely]] {
519+ ts = uv_hrtime ();
520+ }
517521 auto nread = nghttp3_conn_read_stream2 (
518- *this , id, data, datalen, flags.fin ? 1 : 0 , uv_hrtime () );
522+ *this , id, data, datalen, flags.fin ? 1 : 0 , ts );
519523
520524 if (nread < 0 ) {
521525 Debug (&session (),
@@ -665,6 +669,11 @@ class Http3ApplicationImpl final : public Session::Application {
665669 session ().Close ();
666670 }
667671
672+ void StreamRemoved (stream_id id) override {
673+ if (conn_) nghttp3_conn_set_stream_user_data (*this , id, nullptr );
674+ header_state_.erase (id);
675+ }
676+
668677 bool SendHeaders (const Stream& stream,
669678 HeadersKind kind,
670679 const Local<Array>& headers,
@@ -944,7 +953,7 @@ class Http3ApplicationImpl final : public Session::Application {
944953 }
945954
946955 void OnBeginHeaders (stream_id id) {
947- auto stream = FindOrCreateStream (conn_. get (), & session (), id);
956+ auto stream = FindOrCreateStream (id);
948957 if (!stream) [[unlikely]]
949958 return ;
950959 Debug (&session (),
@@ -997,7 +1006,7 @@ class Http3ApplicationImpl final : public Session::Application {
9971006 }
9981007
9991008 void OnBeginTrailers (stream_id id) {
1000- auto stream = FindOrCreateStream (conn_. get (), & session (), id);
1009+ auto stream = FindOrCreateStream (id);
10011010 if (!stream) [[unlikely]]
10021011 return ;
10031012 Debug (&session (),
@@ -1208,13 +1217,19 @@ class Http3ApplicationImpl final : public Session::Application {
12081217 return app;
12091218 }
12101219
1211- static BaseObjectWeakPtr<Stream> FindOrCreateStream (nghttp3_conn* conn,
1212- Session* session,
1213- stream_id id) {
1214- if (auto stream = session->FindStream (id)) {
1220+ // Persist the Stream* in the stream user data, so we can look it
1221+ // up directly without a FindStream map lookup every time.
1222+ void BindStreamUserData (stream_id id, Stream* stream) {
1223+ if (conn_) nghttp3_conn_set_stream_user_data (*this , id, stream);
1224+ }
1225+
1226+ BaseObjectWeakPtr<Stream> FindOrCreateStream (stream_id id) {
1227+ if (auto stream = session ().FindStream (id)) {
1228+ BindStreamUserData (id, stream.get ());
12151229 return stream;
12161230 }
1217- if (auto stream = session->CreateStream (id)) {
1231+ if (auto stream = session ().CreateStream (id)) {
1232+ BindStreamUserData (id, stream.get ());
12181233 return stream;
12191234 }
12201235 return {};
@@ -1238,8 +1253,11 @@ class Http3ApplicationImpl final : public Session::Application {
12381253 auto & app = *ptr;
12391254 NgHttp3CallbackScope scope (&app.session ());
12401255
1241- auto stream = app.session ().FindStream (id);
1242- if (!stream) return NGHTTP3_ERR_CALLBACK_FAILURE ;
1256+ BaseObjectPtr<Stream> stream (static_cast <Stream*>(stream_user_data));
1257+ if (!stream) [[unlikely]] {
1258+ stream = app.session ().FindStream (id);
1259+ if (!stream) return NGHTTP3_ERR_CALLBACK_FAILURE ;
1260+ }
12431261
12441262 if (stream->is_eos ()) {
12451263 *pflags |= NGHTTP3_DATA_FLAG_EOF ;
@@ -1320,7 +1338,11 @@ class Http3ApplicationImpl final : public Session::Application {
13201338 auto ptr = From (conn, conn_user_data);
13211339 CHECK_NOT_NULL (ptr);
13221340 auto & app = *ptr;
1323- if (auto stream = app.session ().FindStream (id)) {
1341+ BaseObjectPtr<Stream> stream (static_cast <Stream*>(stream_user_data));
1342+ if (!stream) [[unlikely]] {
1343+ stream = app.session ().FindStream (id);
1344+ }
1345+ if (stream) {
13241346 stream->Acknowledge (static_cast <size_t >(datalen));
13251347 }
13261348 return NGTCP2_SUCCESS ;
@@ -1351,12 +1373,16 @@ class Http3ApplicationImpl final : public Session::Application {
13511373 if (app.is_control_stream (id)) [[unlikely]] {
13521374 return NGHTTP3_ERR_CALLBACK_FAILURE ;
13531375 }
1354- auto & session = app.session ();
1355- if (auto stream = FindOrCreateStream (conn, &session, id)) [[likely]] {
1356- stream->ReceiveData (data, datalen, Stream::ReceiveDataFlags{});
1357- return NGTCP2_SUCCESS ;
1376+ BaseObjectPtr<Stream> stream (static_cast <Stream*>(stream_user_data));
1377+ if (!stream) [[unlikely]] {
1378+ if (auto created = app.FindOrCreateStream (id)) {
1379+ created->ReceiveData (data, datalen, Stream::ReceiveDataFlags{});
1380+ return NGTCP2_SUCCESS ;
1381+ }
1382+ return NGHTTP3_ERR_CALLBACK_FAILURE ;
13581383 }
1359- return NGHTTP3_ERR_CALLBACK_FAILURE ;
1384+ stream->ReceiveData (data, datalen, Stream::ReceiveDataFlags{});
1385+ return NGTCP2_SUCCESS ;
13601386 }
13611387
13621388 static int on_deferred_consume (nghttp3_conn* conn,
0 commit comments