@@ -118,21 +118,31 @@ std::string QuicStream::diagnostic_name() const {
118118 " , " + session_->diagnostic_name () + " )" ;
119119}
120120
121- void QuicStream::Destroy () {
121+ void QuicStream::Destroy (QuicError* error ) {
122122 if (is_destroyed ())
123123 return ;
124+
125+ QuicSession::SendSessionScope send_scope (session ());
126+
124127 set_flag (QUICSTREAM_FLAG_DESTROYED);
125128 set_flag (QUICSTREAM_FLAG_READ_CLOSED);
126- streambuf_.End ();
129+
130+ // In case this stream is scheduled for sending, remove it
131+ // from the schedule queue
132+ Unschedule ();
127133
128134 // If there is data currently buffered in the streambuf_,
129135 // then cancel will call out to invoke an arbitrary
130136 // JavaScript callback (the on write callback). Within
131137 // that callback, however, the QuicStream will no longer
132138 // be usable to send or receive data.
139+ streambuf_.End ();
133140 streambuf_.Cancel ();
134141 CHECK_EQ (streambuf_.length (), 0 );
135142
143+ // Attempt to send a shutdown signal to the remote peer
144+ ResetStream (error != nullptr ? error->code : NGTCP2_NO_ERROR);
145+
136146 // The QuicSession maintains a map of std::unique_ptrs to
137147 // QuicStream instances. Removing this here will cause
138148 // this QuicStream object to be deconstructed, so the
@@ -411,9 +421,11 @@ void OpenBidirectionalStream(const FunctionCallbackInfo<Value>& args) {
411421}
412422
413423void QuicStreamDestroy (const FunctionCallbackInfo<Value>& args) {
424+ Environment* env = Environment::GetCurrent (args);
414425 QuicStream* stream;
415426 ASSIGN_OR_RETURN_UNWRAP (&stream, args.Holder ());
416- stream->Destroy ();
427+ QuicError error (env, args[0 ], args[1 ], QUIC_ERROR_APPLICATION);
428+ stream->Destroy (&error);
417429}
418430
419431void QuicStreamReset (const FunctionCallbackInfo<Value>& args) {
@@ -428,6 +440,18 @@ void QuicStreamReset(const FunctionCallbackInfo<Value>& args) {
428440 error.code : static_cast <uint64_t >(NGTCP2_NO_ERROR));
429441}
430442
443+ void QuicStreamStopSending (const FunctionCallbackInfo<Value>& args) {
444+ Environment* env = Environment::GetCurrent (args);
445+ QuicStream* stream;
446+ ASSIGN_OR_RETURN_UNWRAP (&stream, args.Holder ());
447+
448+ QuicError error (env, args[0 ], args[1 ], QUIC_ERROR_APPLICATION);
449+
450+ stream->StopSending (
451+ error.family == QUIC_ERROR_APPLICATION ?
452+ error.code : static_cast <uint64_t >(NGTCP2_NO_ERROR));
453+ }
454+
431455// Requests transmission of a block of informational headers. Not all
432456// QUIC Applications will support headers. If headers are not supported,
433457// This will set the return value to false, otherwise the return value
@@ -494,6 +518,7 @@ void QuicStream::Initialize(
494518 streamt->Set (env->owner_symbol (), Null (env->isolate ()));
495519 env->SetProtoMethod (stream, " destroy" , QuicStreamDestroy);
496520 env->SetProtoMethod (stream, " resetStream" , QuicStreamReset);
521+ env->SetProtoMethod (stream, " stopSending" , QuicStreamStopSending);
497522 env->SetProtoMethod (stream, " id" , QuicStreamGetID);
498523 env->SetProtoMethod (stream, " submitInformation" , QuicStreamSubmitInformation);
499524 env->SetProtoMethod (stream, " submitHeaders" , QuicStreamSubmitHeaders);
0 commit comments