GeezerVison is showing github.com — quic: correct http3 callback and fix revealed errs · nodejs/node@2ef4b7e
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/quic/quic.js +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -2543,8 +2543,8 @@ class QuicStream { | 2543 | 2543 | inner.ontrailers = undefined; | 2544 | 2544 | inner.oninfo = undefined; | 2545 | 2545 | inner.onwanttrailers = undefined; | 2546 | | - inner.headers = undefined; | 2547 | | - inner.pendingTrailers = undefined; | | 2546 | + // Do not reset headers here, this is still important information | | 2547 | + // the same applies for pendingTrailers | 2548 | 2548 | this.#handle = undefined; | 2549 | 2549 | if (inner.fileHandle !== undefined) { | 2550 | 2550 | // Close the FileHandle that was used as a body source. The close | |
Collapse file Copy file name to clipboardExpand all lines: src/quic/http3.cc +23-20Lines changed: 23 additions & 20 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -921,24 +921,25 @@ class Http3ApplicationImpl final : public Session::Application { | 921 | 921 | stream->ReceiveData(nullptr, 0, flags); | 922 | 922 | } | 923 | 923 |
| 924 | | - void OnStopSending(stream_id id, error_code app_error_code) { | | 924 | + void OnSendStopSending(stream_id id, error_code app_error_code) { | 925 | 925 | auto stream = session().FindStream(id); | 926 | 926 | if (!stream) [[unlikely]] | 927 | 927 | return; | 928 | 928 | Debug(&session(), | 929 | | - "HTTP/3 application received stop sending for stream %" PRIi64, | | 929 | + "HTTP/3 application should send stop sending for stream %" PRIi64, | 930 | 930 | id); | 931 | | - stream->ReceiveStopSending(QuicError::ForApplication(app_error_code)); | | 931 | + stream->SendStopSending(app_error_code); | 932 | 932 | } | 933 | 933 |
| 934 | | - void OnResetStream(stream_id id, error_code app_error_code) { | | 934 | + void OnDoResetStream(stream_id id, error_code app_error_code) { | 935 | 935 | auto stream = session().FindStream(id); | 936 | 936 | if (!stream) [[unlikely]] | 937 | 937 | return; | 938 | 938 | Debug(&session(), | 939 | | - "HTTP/3 application received reset stream for stream %" PRIi64, | | 939 | + "HTTP/3 application received a request to reset stream for stream " | | 940 | + "%" PRIi64, | 940 | 941 | id); | 941 | | - stream->ReceiveStreamReset(0, QuicError::ForApplication(app_error_code)); | | 942 | + stream->DoStreamReset(app_error_code); | 942 | 943 | } | 943 | 944 |
| 944 | 945 | void OnShutdown(stream_id id) { | @@ -1318,29 +1319,31 @@ class Http3ApplicationImpl final : public Session::Application { | 1318 | 1319 | return NGTCP2_SUCCESS; | 1319 | 1320 | } | 1320 | 1321 |
| 1321 | | - static int on_stop_sending(nghttp3_conn* conn, | 1322 | | - stream_id id, | 1323 | | - error_code app_error_code, | 1324 | | - void* conn_user_data, | 1325 | | - void* stream_user_data) { | | 1322 | + static int on_send_stop_sending(nghttp3_conn* conn, | | 1323 | + stream_id id, | | 1324 | + error_code app_error_code, | | 1325 | + void* conn_user_data, | | 1326 | + void* stream_user_data) { | | 1327 | + // this callback asks the app side to send a stop sending | 1326 | 1328 | NGHTTP3_CALLBACK_SCOPE(app); | 1327 | 1329 | if (app.is_control_stream(id)) [[unlikely]] { | 1328 | 1330 | return NGHTTP3_ERR_CALLBACK_FAILURE; | 1329 | 1331 | } | 1330 | | - app.OnStopSending(id, app_error_code); | | 1332 | + app.OnSendStopSending(id, app_error_code); | 1331 | 1333 | return NGTCP2_SUCCESS; | 1332 | 1334 | } | 1333 | 1335 |
| 1334 | | - static int on_reset_stream(nghttp3_conn* conn, | 1335 | | - stream_id id, | 1336 | | - error_code app_error_code, | 1337 | | - void* conn_user_data, | 1338 | | - void* stream_user_data) { | | 1336 | + static int on_do_reset_stream(nghttp3_conn* conn, | | 1337 | + stream_id id, | | 1338 | + error_code app_error_code, | | 1339 | + void* conn_user_data, | | 1340 | + void* stream_user_data) { | | 1341 | + // this callback ask the app side to do a reset stream | 1339 | 1342 | NGHTTP3_CALLBACK_SCOPE(app); | 1340 | 1343 | if (app.is_control_stream(id)) [[unlikely]] { | 1341 | 1344 | return NGHTTP3_ERR_CALLBACK_FAILURE; | 1342 | 1345 | } | 1343 | | - app.OnResetStream(id, app_error_code); | | 1346 | + app.OnDoResetStream(id, app_error_code); | 1344 | 1347 | return NGTCP2_SUCCESS; | 1345 | 1348 | } | 1346 | 1349 |
| @@ -1394,9 +1397,9 @@ class Http3ApplicationImpl final : public Session::Application { | 1394 | 1397 | on_begin_trailers, | 1395 | 1398 | on_receive_trailer, | 1396 | 1399 | on_end_trailers, | 1397 | | - on_stop_sending, | | 1400 | + on_send_stop_sending, | 1398 | 1401 | on_end_stream, | 1399 | | - on_reset_stream, | | 1402 | + on_do_reset_stream, | 1400 | 1403 | on_shutdown, | 1401 | 1404 | nullptr, // recv_settings (deprecated) | 1402 | 1405 | on_receive_origin, | |
Collapse file Copy file name to clipboardExpand all lines: src/quic/session.cc +2-1Lines changed: 2 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -2806,7 +2806,8 @@ void Session::RemoveStream(stream_id id) { | 2806 | 2806 | // then we can proceed to finishing the close now. Note that the | 2807 | 2807 | // expectation is that the session will be destroyed once FinishClose | 2808 | 2808 | // returns. | 2809 | | - if (impl_->state()->closing && impl_->state()->graceful_close) { | | 2809 | + if (impl_->state()->closing && impl_->state()->graceful_close && | | 2810 | + impl_->streams_.size() == 0) { | 2810 | 2811 | FinishClose(); | 2811 | 2812 | CHECK(is_destroyed()); | 2812 | 2813 | } | |
Collapse file Copy file name to clipboardExpand all lines: src/quic/streams.cc +32-24Lines changed: 32 additions & 24 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -487,15 +487,7 @@ struct Stream::Impl { | 487 | 487 | code = args[0].As<BigInt>()->Uint64Value(&unused); | 488 | 488 | } | 489 | 489 |
| 490 | | - stream->EndReadable(); | 491 | | - | 492 | | - if (!stream->is_pending()) { | 493 | | - // If the stream is a local unidirectional there's nothing to do here. | 494 | | - if (stream->is_local_unidirectional()) return; | 495 | | - stream->NotifyReadableEnded(code); | 496 | | - } else { | 497 | | - stream->pending_close_read_code_ = code; | 498 | | - } | | 490 | + stream->SendStopSending(code); | 499 | 491 | } | 500 | 492 |
| 501 | 493 | // Sends a reset stream to the peer to tell it we will not be sending any | @@ -512,21 +504,7 @@ struct Stream::Impl { | 512 | 504 | code = args[0].As<BigInt>()->Uint64Value(&lossless); | 513 | 505 | } | 514 | 506 |
| 515 | | - if (stream->state()->reset == 1) return; | 516 | | - | 517 | | - stream->EndWritable(); | 518 | | - // We can release our outbound here now. Since the stream is being reset | 519 | | - // on the ngtcp2 side, we do not need to keep any of the data around | 520 | | - // waiting for acknowledgement that will never come. | 521 | | - stream->outbound_.reset(); | 522 | | - stream->state()->reset = 1; | 523 | | - | 524 | | - if (!stream->is_pending()) { | 525 | | - if (stream->is_remote_unidirectional()) return; | 526 | | - stream->NotifyWritableEnded(code); | 527 | | - } else { | 528 | | - stream->pending_close_write_code_ = code; | 529 | | - } | | 507 | + stream->DoStreamReset(code); | 530 | 508 | } | 531 | 509 |
| 532 | 510 | JS_METHOD(SetPriority) { | @@ -1827,6 +1805,36 @@ void Stream::ReceiveStreamReset(uint64_t final_size, QuicError error) { | 1827 | 1805 | EmitReset(error); | 1828 | 1806 | } | 1829 | 1807 |
| | 1808 | +void Stream::DoStreamReset(error_code code) { | | 1809 | + if (state()->reset == 1) return; | | 1810 | + | | 1811 | + EndWritable(); | | 1812 | + // We can release our outbound here now. Since the stream is being reset | | 1813 | + // on the ngtcp2 side, we do not need to keep any of the data around | | 1814 | + // waiting for acknowledgement that will never come. | | 1815 | + outbound_.reset(); | | 1816 | + state()->reset = 1; | | 1817 | + | | 1818 | + if (!is_pending()) { | | 1819 | + if (is_remote_unidirectional()) return; | | 1820 | + NotifyWritableEnded(code); | | 1821 | + } else { | | 1822 | + pending_close_write_code_ = code; | | 1823 | + } | | 1824 | +} | | 1825 | + | | 1826 | +void Stream::SendStopSending(error_code code) { | | 1827 | + EndReadable(); | | 1828 | + | | 1829 | + if (!is_pending()) { | | 1830 | + // If the stream is a local unidirectional there's nothing to do here. | | 1831 | + if (is_local_unidirectional()) return; | | 1832 | + NotifyReadableEnded(code); | | 1833 | + } else { | | 1834 | + pending_close_read_code_ = code; | | 1835 | + } | | 1836 | +} | | 1837 | + | 1830 | 1838 | // ============================================================================ | 1831 | 1839 |
| 1832 | 1840 | void Stream::EmitBlocked() { | |
Collapse file Copy file name to clipboardExpand all lines: src/quic/streams.h +11Lines changed: 11 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -344,6 +344,17 @@ class Stream final : public AsyncWrap, | 344 | 344 | void ReceiveStopSending(QuicError error); | 345 | 345 | void ReceiveStreamReset(uint64_t final_size, QuicError error); | 346 | 346 |
| | 347 | + // Sends a reset stream to the peer to tell it we will not be sending any | | 348 | + // more data for this stream. This has the effect of shutting down the | | 349 | + // writable side of the stream for this peer. Any data that is held in the | | 350 | + // outbound queue will be dropped. The stream may still be readable. | | 351 | + void DoStreamReset(error_code code); | | 352 | + | | 353 | + // Tells the peer to stop sending data for this stream. This has the effect | | 354 | + // of shutting down the readable side of the stream for this peer. Any data | | 355 | + // that has already been received is still readable. | | 356 | + void SendStopSending(error_code code); | | 357 | + | 347 | 358 | // Currently, only HTTP/3 streams support headers. These methods are here | 348 | 359 | // to support that. They are not used when using any other QUIC application. | 349 | 360 |
| |
|