@fails-components/webtransport 0.1.7 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@fails-components/webtransport",
3
- "version": "0.1.7",
3
+ "version": "0.2.1",
4
4
  "description": "A component to add webtransport support (server and client) to node.js using libquiche",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.js",
7
7
  "engines": {
8
- "node": ">=16"
8
+ "node": ">=16.5"
9
9
  },
10
10
  "type": "module",
11
11
  "types": "./dist/lib/index.d.ts",
@@ -60,7 +60,8 @@
60
60
  "mocha": "^10.1.0",
61
61
  "node-forge": "^1.3.1",
62
62
  "prettier": "^2.4.1",
63
- "typescript": "4.8.4"
63
+ "typescript": "4.8.4",
64
+ "uint8arrays": "^4.0.2"
64
65
  },
65
66
  "binary": {
66
67
  "napi_versions": [
@@ -0,0 +1,5 @@
1
+ // adds string to the includes of google url
2
+ #include <string>
3
+ #warning "Fake utf_stream_operators.h included"
4
+
5
+ #include "third_party/googleurl/base/strings/utf_ostream_operators.h"
@@ -12,45 +12,54 @@
12
12
 
13
13
  #include <utility>
14
14
 
15
- namespace quic {
16
-
17
- Http3ClientSession::Http3ClientSession(
18
- const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
19
- QuicConnection* connection, const QuicServerId& server_id,
20
- QuicCryptoClientConfig* crypto_config,
21
- QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body)
22
- : Http3ClientSession(config, supported_versions, connection, server_id,
23
- crypto_config, push_promise_index,
24
- drop_response_body,
25
- /*enable_web_transport=*/false) {}
26
-
27
- Http3ClientSession::Http3ClientSession(
28
- const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
29
- QuicConnection* connection, const QuicServerId& server_id,
30
- QuicCryptoClientConfig* crypto_config,
31
- QuicClientPushPromiseIndex* push_promise_index, bool drop_response_body,
32
- bool enable_web_transport)
33
- : QuicSpdyClientSession(config, supported_versions, connection, server_id,
34
- crypto_config, push_promise_index),
35
- drop_response_body_(drop_response_body),
36
- enable_web_transport_(enable_web_transport) {}
37
-
38
- std::unique_ptr<QuicSpdyClientStream>
39
- Http3ClientSession::CreateClientStream() {
40
- auto stream = std::make_unique<Http3ClientStream>(
41
- GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL,
42
- drop_response_body_);
43
- stream->set_on_interim_headers(on_interim_headers_);
44
- return stream;
45
- }
46
-
47
- bool Http3ClientSession::ShouldNegotiateWebTransport() {
48
- return enable_web_transport_;
49
- }
50
-
51
- HttpDatagramSupport Http3ClientSession::LocalHttpDatagramSupport() {
52
- return enable_web_transport_ ? HttpDatagramSupport::kDraft04
53
- : HttpDatagramSupport::kNone;
54
- }
55
-
56
- } // namespace quic
15
+ namespace quic
16
+ {
17
+
18
+ Http3ClientSession::Http3ClientSession(
19
+ const QuicConfig &config, const ParsedQuicVersionVector &supported_versions,
20
+ QuicConnection *connection, const QuicServerId &server_id,
21
+ QuicCryptoClientConfig *crypto_config,
22
+ QuicClientPushPromiseIndex *push_promise_index, bool drop_response_body)
23
+ : Http3ClientSession(config, supported_versions, connection, server_id,
24
+ crypto_config, push_promise_index,
25
+ drop_response_body,
26
+ /*enable_web_transport=*/false)
27
+ {
28
+ }
29
+
30
+ Http3ClientSession::Http3ClientSession(
31
+ const QuicConfig &config, const ParsedQuicVersionVector &supported_versions,
32
+ QuicConnection *connection, const QuicServerId &server_id,
33
+ QuicCryptoClientConfig *crypto_config,
34
+ QuicClientPushPromiseIndex *push_promise_index, bool drop_response_body,
35
+ bool enable_web_transport)
36
+ : QuicSpdyClientSession(config, supported_versions, connection, server_id,
37
+ crypto_config, push_promise_index),
38
+ drop_response_body_(drop_response_body),
39
+ enable_web_transport_(enable_web_transport) {}
40
+
41
+ std::unique_ptr<QuicSpdyClientStream>
42
+ Http3ClientSession::CreateClientStream()
43
+ {
44
+ auto stream = std::make_unique<Http3ClientStream>(
45
+ GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL,
46
+ drop_response_body_);
47
+ stream->set_on_interim_headers(on_interim_headers_);
48
+ return stream;
49
+ }
50
+
51
+ WebTransportHttp3VersionSet Http3ClientSession::LocallySupportedWebTransportVersions()
52
+ const
53
+ {
54
+ return enable_web_transport_
55
+ ? kDefaultSupportedWebTransportVersions
56
+ : WebTransportHttp3VersionSet();
57
+ }
58
+
59
+ HttpDatagramSupport Http3ClientSession::LocalHttpDatagramSupport()
60
+ {
61
+ return enable_web_transport_ ? HttpDatagramSupport::kRfcAndDraft04
62
+ : HttpDatagramSupport::kNone;
63
+ }
64
+
65
+ } // namespace quic
@@ -17,40 +17,44 @@
17
17
  #include "quiche/quic/core/http/quic_spdy_client_session.h"
18
18
  #include "src/http3clientstream.h"
19
19
 
20
- namespace quic {
21
-
22
- class Http3ClientSession : public QuicSpdyClientSession {
23
- public:
24
- Http3ClientSession(const QuicConfig& config,
25
- const ParsedQuicVersionVector& supported_versions,
26
- QuicConnection* connection,
27
- const QuicServerId& server_id,
28
- QuicCryptoClientConfig* crypto_config,
29
- QuicClientPushPromiseIndex* push_promise_index,
30
- bool drop_response_body);
31
- Http3ClientSession(const QuicConfig& config,
32
- const ParsedQuicVersionVector& supported_versions,
33
- QuicConnection* connection,
34
- const QuicServerId& server_id,
35
- QuicCryptoClientConfig* crypto_config,
36
- QuicClientPushPromiseIndex* push_promise_index,
37
- bool drop_response_body, bool enable_web_transport);
38
-
39
- std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override;
40
- bool ShouldNegotiateWebTransport() override;
41
- HttpDatagramSupport LocalHttpDatagramSupport() override;
42
-
43
- void set_on_interim_headers(
44
- std::function<void(const spdy::Http2HeaderBlock&)> on_interim_headers) {
45
- on_interim_headers_ = std::move(on_interim_headers);
46
- }
47
-
48
- private:
49
- std::function<void(const spdy::Http2HeaderBlock&)> on_interim_headers_;
50
- const bool drop_response_body_;
51
- const bool enable_web_transport_;
52
- };
53
-
54
- } // namespace quic
55
-
56
- #endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
20
+ namespace quic
21
+ {
22
+
23
+ class Http3ClientSession : public QuicSpdyClientSession
24
+ {
25
+ public:
26
+ Http3ClientSession(const QuicConfig &config,
27
+ const ParsedQuicVersionVector &supported_versions,
28
+ QuicConnection *connection,
29
+ const QuicServerId &server_id,
30
+ QuicCryptoClientConfig *crypto_config,
31
+ QuicClientPushPromiseIndex *push_promise_index,
32
+ bool drop_response_body);
33
+ Http3ClientSession(const QuicConfig &config,
34
+ const ParsedQuicVersionVector &supported_versions,
35
+ QuicConnection *connection,
36
+ const QuicServerId &server_id,
37
+ QuicCryptoClientConfig *crypto_config,
38
+ QuicClientPushPromiseIndex *push_promise_index,
39
+ bool drop_response_body, bool enable_web_transport);
40
+
41
+ std::unique_ptr<QuicSpdyClientStream> CreateClientStream() override;
42
+ WebTransportHttp3VersionSet LocallySupportedWebTransportVersions()
43
+ const override;
44
+ HttpDatagramSupport LocalHttpDatagramSupport() override;
45
+
46
+ void set_on_interim_headers(
47
+ std::function<void(const spdy::Http2HeaderBlock &)> on_interim_headers)
48
+ {
49
+ on_interim_headers_ = std::move(on_interim_headers);
50
+ }
51
+
52
+ private:
53
+ std::function<void(const spdy::Http2HeaderBlock &)> on_interim_headers_;
54
+ const bool drop_response_body_;
55
+ const bool enable_web_transport_;
56
+ };
57
+
58
+ } // namespace quic
59
+
60
+ #endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_CLIENT_SESSION_H_
@@ -149,13 +149,14 @@ namespace quic
149
149
  progress_->Send(&report, 1);
150
150
  }
151
151
 
152
- void Http3EventLoop::informAboutStreamRead(Http3WTStream *streamobj, std::string *data, bool fin)
152
+ void Http3EventLoop::informAboutStreamRead(Http3WTStream *streamobj, uint32_t buffergrow, bool fin, bool success)
153
153
  {
154
154
  Http3ProgressReport report;
155
155
  report.type = Http3ProgressReport::StreamRead;
156
156
  report.streamobj = streamobj;
157
- report.para = data;
158
157
  report.fin = fin;
158
+ report.buffergrow = buffergrow;
159
+ report.success = success;
159
160
  if (progress_)
160
161
  progress_->Send(&report, 1);
161
162
  }
@@ -210,6 +211,15 @@ namespace quic
210
211
  progress_->Send(&report, 1);
211
212
  }
212
213
 
214
+ void Http3EventLoop::informGoawayReceived(Http3WTSession *sessionobj)
215
+ {
216
+ Http3ProgressReport report;
217
+ report.type = Http3ProgressReport::GoawayReceived;
218
+ report.sessionobj = sessionobj;
219
+ if (progress_)
220
+ progress_->Send(&report, 1);
221
+ }
222
+
213
223
  void Http3EventLoop::informUnref(LifetimeHelper *obj)
214
224
  {
215
225
  Http3ProgressReport report;
@@ -354,6 +364,13 @@ namespace quic
354
364
  Http3WTStreamJS *strjs = Napi::ObjectWrap<Http3WTStreamJS>::Unwrap(strobj);
355
365
  strjs->setObj(stream);
356
366
  if (!stream->gone()) strjs->Ref();
367
+
368
+ if (incom || bidi) { // we have a read stream
369
+ // same size of a pipe in chromium, but the WT Pipe thre is 256 kbyte, the default 64 kbyte
370
+ Napi::ArrayBuffer arraybuf = Napi::ArrayBuffer::New(qw_->Env(), 64 * 1024);
371
+ strobj.Set("readbuffer", arraybuf); // so the lifecycle is bound to the JS Obj!
372
+ stream->setReadBuffer(arraybuf.Data(), arraybuf.ByteLength());
373
+ }
357
374
  stream->setJS(strjs);
358
375
 
359
376
  Napi::Object objVal = sessionobj->getJS()->Value();
@@ -409,19 +426,12 @@ namespace quic
409
426
  cbstream_.Call({retObj});
410
427
  }
411
428
 
412
- void Http3EventLoop::processStreamRead(Http3WTStream *streamobj, std::string *data, bool fin)
429
+ void Http3EventLoop::processStreamRead(Http3WTStream *streamobj, size_t buffergrow, bool fin, bool success)
413
430
  {
414
431
  if (!checkQw())
415
432
  return;
416
433
  HandleScope scope(qw_->Env());
417
434
 
418
- Napi::Object dataVal =
419
- Napi::Uint8Array::New(qw_->Env(),
420
- data->length(),
421
- Napi::ArrayBuffer::New(qw_->Env(), &(*data)[0], data->length(),
422
- freeData, data),
423
- 0);
424
-
425
435
  auto stream = streamobj->getJS();
426
436
  if (!stream)
427
437
  return;
@@ -430,8 +440,9 @@ namespace quic
430
440
  Napi::Object retObj = Napi::Object::New(qw_->Env());
431
441
  retObj.Set("purpose", "StreamRead");
432
442
  retObj.Set("fin", fin);
433
- retObj.Set("data", dataVal);
443
+ retObj.Set("buffergrow", buffergrow);
434
444
  retObj.Set("object", objVal);
445
+ retObj.Set("success", success);
435
446
 
436
447
  cbstream_.Call({retObj});
437
448
  }
@@ -562,6 +573,24 @@ namespace quic
562
573
  cbsession_.Call({retObj});
563
574
  }
564
575
 
576
+ void Http3EventLoop::processGoawayReceived(Http3WTSession *sessionobj)
577
+ {
578
+ if (!checkQw())
579
+ return;
580
+ HandleScope scope(qw_->Env());
581
+
582
+
583
+ auto session = sessionobj->getJS();
584
+ if (!session)
585
+ return;
586
+ Napi::Object objVal = session->Value();
587
+
588
+ Napi::Object retObj = Napi::Object::New(qw_->Env());
589
+ retObj.Set("purpose", "GoawayReceived");
590
+ retObj.Set("object", objVal);
591
+ cbsession_.Call({retObj});
592
+ }
593
+
565
594
  void Http3EventLoop::processNewSessionRequest(Http3Server *serverobj, WebTransportSession *session, spdy::Http2HeaderBlock *reqheadcopy, WebTransportRespPromisePtr *promise)
566
595
  {
567
596
  if (!checkQw())
@@ -820,8 +849,7 @@ namespace quic
820
849
  break;
821
850
  case Http3ProgressReport::StreamRead:
822
851
  {
823
- processStreamRead(cur.streamobj, cur.para, cur.fin);
824
- cur.para = nullptr; // take ownership of the data
852
+ processStreamRead(cur.streamobj, cur.buffergrow, cur.fin, cur.success);
825
853
  }
826
854
  break;
827
855
  case Http3ProgressReport::StreamWrite:
@@ -850,6 +878,11 @@ namespace quic
850
878
  processDatagramSend(cur.sessionobj, cur.bufferhandle);
851
879
  }
852
880
  break;
881
+ case Http3ProgressReport::GoawayReceived:
882
+ {
883
+ processGoawayReceived(cur.sessionobj);
884
+ }
885
+ break;
853
886
  case Http3ProgressReport::Unref:
854
887
  {
855
888
  cur.obj->doUnref();
@@ -93,6 +93,7 @@ namespace quic
93
93
  StreamNetworkFinish,
94
94
  DatagramReceived,
95
95
  DatagramSend,
96
+ GoawayReceived,
96
97
  Unref
97
98
  } type;
98
99
  union
@@ -109,6 +110,7 @@ namespace quic
109
110
  NetworkTask nettask;
110
111
  NetworkStatus status;
111
112
  WebTransportSession *webtsession;
113
+ uint32_t buffergrow;
112
114
  };
113
115
  union
114
116
  {
@@ -209,7 +211,7 @@ namespace quic
209
211
 
210
212
  void informAboutStream(bool incom, bool bidir, Http3WTSession *sessionobj, Http3WTStream *stream);
211
213
  void informStreamRecvSignal(Http3WTStream *streamobj, WebTransportStreamError error_code, NetworkTask task);
212
- void informAboutStreamRead(Http3WTStream *streamobj, std::string *data, bool fin);
214
+ void informAboutStreamRead(Http3WTStream *streamobj, uint32_t buffergrow, bool fin, bool success);
213
215
  void informAboutStreamWrite(Http3WTStream *streamobj, Napi::ObjectReference *bufferhandle, bool success);
214
216
  void informAboutStreamReset(Http3WTStream *streamobj);
215
217
  void informAboutStreamNetworkFinish(Http3WTStream *streamobj, NetworkTask task);
@@ -217,6 +219,8 @@ namespace quic
217
219
  void informDatagramReceived(Http3WTSession *sessionobj, absl::string_view datagram);
218
220
  void informDatagramSend(Http3WTSession *sessionobj, Napi::ObjectReference *bufferhandle);
219
221
 
222
+ void informGoawayReceived(Http3WTSession *sessionobj);
223
+
220
224
  void informUnref(LifetimeHelper *obj);
221
225
 
222
226
  void Schedule(std::function<void()> action);
@@ -274,7 +278,7 @@ namespace quic
274
278
 
275
279
  void processStream(bool incom, bool bidi, Http3WTSession *sessionobj, Http3WTStream *stream);
276
280
  void processStreamRecvSignal(Http3WTStream *streamobj, WebTransportStreamError error_code, NetworkTask task);
277
- void processStreamRead(Http3WTStream *streamobj, std::string *data, bool fin);
281
+ void processStreamRead(Http3WTStream *streamobj, size_t buffergrow, bool fin, bool success);
278
282
  void processStreamWrite(Http3WTStream *streamobj, Napi::ObjectReference *bufferhandle, bool success);
279
283
  void processStreamReset(Http3WTStream *streamobj);
280
284
  void processStreamNetworkFinish(Http3WTStream *streamobj, NetworkTask task);
@@ -282,6 +286,8 @@ namespace quic
282
286
  void processDatagramReceived(Http3WTSession *sessionobj, std::string *datagram);
283
287
  void processDatagramSend(Http3WTSession *sessionobj, Napi::ObjectReference *bufferhandle);
284
288
 
289
+ void processGoawayReceived(Http3WTSession *sessionobj);
290
+
285
291
  bool shutDownEventLoopInt();
286
292
 
287
293
  const AsyncProgressQueueWorker<Http3ProgressReport>::ExecutionProgress *progress_;
@@ -69,7 +69,7 @@ namespace quic
69
69
 
70
70
  if (!socket_api.Bind(fd_, address))
71
71
  {
72
- QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno) << "\n";
72
+ QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno) << " for " << address.ToString() << "\n";
73
73
  return false;
74
74
  }
75
75
  QUIC_LOG(INFO) << "Listening on " << address.ToString() << "\n";
@@ -26,7 +26,7 @@
26
26
  #include "quiche/quic/core/http/quic_spdy_session.h"
27
27
  #include "quiche/quic/core/quic_crypto_server_stream_base.h"
28
28
  #include "quiche/quic/core/quic_packets.h"
29
- //#include "quic/tools/quic_backend_response.h"
29
+ // #include "quic/tools/quic_backend_response.h"
30
30
  #include "src/http3serverbackend.h"
31
31
  #include "src/http3serverstream.h" // todo
32
32
 
@@ -36,7 +36,6 @@ namespace quic
36
36
  class Http3ServerSession : public QuicServerSessionBase
37
37
  {
38
38
  public:
39
-
40
39
  // Takes ownership of |connection|.
41
40
  Http3ServerSession(const QuicConfig &config,
42
41
  const ParsedQuicVersionVector &supported_versions,
@@ -54,7 +53,6 @@ namespace quic
54
53
  // Override base class to detact client sending data on server push stream.
55
54
  void OnStreamFrame(const QuicStreamFrame &frame) override;
56
55
 
57
-
58
56
  protected:
59
57
  // QuicSession methods:
60
58
  QuicSpdyStream *CreateIncomingStream(QuicStreamId id) override;
@@ -72,11 +70,14 @@ namespace quic
72
70
  return http3_server_backend_;
73
71
  }
74
72
 
75
-
76
- bool ShouldNegotiateWebTransport() override
73
+ WebTransportHttp3VersionSet LocallySupportedWebTransportVersions()
74
+ const override
77
75
  {
78
- return http3_server_backend_->SupportsWebTransport();
76
+ return http3_server_backend_->SupportsWebTransport()
77
+ ? kDefaultSupportedWebTransportVersions
78
+ : WebTransportHttp3VersionSet();
79
79
  }
80
+
80
81
  HttpDatagramSupport LocalHttpDatagramSupport() override
81
82
  {
82
83
  if (ShouldNegotiateWebTransport())
@@ -85,7 +86,7 @@ namespace quic
85
86
  }
86
87
  return QuicServerSessionBase::LocalHttpDatagramSupport();
87
88
  }
88
-
89
+
89
90
  Http3ServerBackend *http3_server_backend_; // Not owned.
90
91
  };
91
92
 
@@ -52,6 +52,11 @@ namespace quic
52
52
  {
53
53
  session_ = session;
54
54
  eventloop_ = eventloop;
55
+ if (session_) {
56
+ session_->SetOnDraining([this]() {
57
+ eventloop_->informGoawayReceived(this);
58
+ });
59
+ }
55
60
  }
56
61
 
57
62
  class Visitor : public WebTransportVisitor
@@ -218,6 +223,13 @@ namespace quic
218
223
  eventloop_->Schedule(task);
219
224
  }
220
225
 
226
+ void notifySessionDrainingInt()
227
+ {
228
+ std::function<void()> task = [this]()
229
+ { if (session_) session_->NotifySessionDraining(); };
230
+ eventloop_->Schedule(task);
231
+ }
232
+
221
233
  void closeInt(int code, std::string &reason)
222
234
  {
223
235
  std::function<void()> task = [this, code, reason]()
@@ -283,6 +295,11 @@ namespace quic
283
295
  }
284
296
  }
285
297
 
298
+ void notifySessionDraining(const Napi::CallbackInfo &info)
299
+ {
300
+ wtsession_->notifySessionDrainingInt();
301
+ }
302
+
286
303
  void close(const Napi::CallbackInfo &info)
287
304
  {
288
305
  int code = 0;
@@ -319,6 +336,8 @@ namespace quic
319
336
  static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
320
337
  InstanceMethod<&Http3WTSessionJS::writeDatagram>("writeDatagram",
321
338
  static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
339
+ InstanceMethod<&Http3WTSessionJS::notifySessionDraining>("notifySessionDraining",
340
+ static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
322
341
  InstanceMethod<&Http3WTSessionJS::close>("close",
323
342
  static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
324
343
  constr->session = Napi::Persistent(tplwt);
@@ -23,6 +23,9 @@ namespace quic
23
23
 
24
24
  stream_->chunks_.pop_front();
25
25
  }
26
+
27
+ stream_->eventloop_->informAboutStreamRead(stream_, 0, false, false);
28
+
26
29
  if (!stream_->stop_sending_received_)
27
30
  {
28
31
  stream_->eventloop_->informStreamRecvSignal(stream_, 0, NetworkTask::stopSending);
@@ -77,21 +80,45 @@ namespace quic
77
80
 
78
81
  void Http3WTStream::doCanRead()
79
82
  {
83
+ // if (pause_reading_) return ; // back pressure folks!
84
+
80
85
  if (pause_reading_)
81
86
  {
82
87
  can_read_pending_ = true;
83
88
  return; // back pressure folks!
84
89
  }
85
90
  // first figure out if we have readable data
91
+ if (bufferlen_ >= readbufsize_ || !readbufdata_) {
92
+ can_read_pending_ = true;
93
+ return; // no space here
94
+ }
86
95
  size_t readable = stream_->ReadableBytes();
87
- // ok create a string obj to hold the data
88
- std::string *data = new std::string();
89
- data->resize(readable);
90
- WebTransportStream::ReadResult result = stream_->Read(absl::Span<char>(&(*data)[0], readable));
91
- data->resize(result.bytes_read);
92
- QUIC_DVLOG(1) << "Attempted reading on WebTransport bidirectional stream "
93
- << ", bytes read: " << result.bytes_read;
94
- eventloop_->informAboutStreamRead(this, data, result.fin);
96
+ bool read = false;
97
+ while (readable > 0 && bufferlen_ < readbufsize_)
98
+ {
99
+ if (writepos_ >= readpos_) {
100
+ size_t len = readbufsize_ - writepos_;
101
+ WebTransportStream::ReadResult result =
102
+ stream_->Read(absl::Span<char>(((char*) readbufdata_) + writepos_, len));
103
+ QUIC_DVLOG(1) << "Attempted reading on WebTransport stream "
104
+ << ", bytes read: " << result.bytes_read;
105
+ writepos_ = (writepos_ + result.bytes_read) % readbufsize_;
106
+ bufferlen_ = bufferlen_ + result.bytes_read;
107
+ eventloop_->informAboutStreamRead(this, result.bytes_read,
108
+ result.fin, true);
109
+ } else { // readpos_ > writepos_
110
+ size_t len = writepos_ - readpos_;
111
+ WebTransportStream::ReadResult result =
112
+ stream_->Read(absl::Span<char>(((char*) readbufdata_) + writepos_, len));
113
+ QUIC_DVLOG(1) << "Attempted reading on WebTransport stream "
114
+ << ", bytes read: " << result.bytes_read;
115
+ writepos_ = (writepos_ + result.bytes_read) % readbufsize_;
116
+ bufferlen_ = bufferlen_ + result.bytes_read;
117
+ eventloop_->informAboutStreamRead(this, result.bytes_read,
118
+ result.fin, true);
119
+ }
120
+ readable = stream_->ReadableBytes();
121
+ }
95
122
  }
96
123
 
97
124
  void Http3WTStream::doCanWrite()