@fails-components/webtransport 0.1.5 → 0.2.0
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/CMakeLists.txt +42 -111
- package/build.js +4 -4
- package/dist/lib/dom.d.ts +6 -0
- package/dist/lib/dom.d.ts.map +1 -1
- package/dist/lib/event-loop.d.ts +8 -3
- package/dist/lib/event-loop.d.ts.map +1 -1
- package/dist/lib/server.d.ts +3 -2
- package/dist/lib/server.d.ts.map +1 -1
- package/dist/lib/session.d.ts +78 -18
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/stream.d.ts +13 -5
- package/dist/lib/stream.d.ts.map +1 -1
- package/dist/lib/transport.d.ts.map +1 -1
- package/dist/lib/types.d.ts +11 -2
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/webtransport.d.ts +22 -0
- package/dist/lib/webtransport.d.ts.map +1 -1
- package/dist/test/bidirectional-streams.spec.d.ts.map +1 -1
- package/dist/test/datagrams.spec.d.ts.map +1 -1
- package/dist/test/fixtures/p-timeout.d.ts +8 -0
- package/dist/test/fixtures/p-timeout.d.ts.map +1 -0
- package/dist/test/fixtures/read-stream.d.ts.map +1 -1
- package/dist/test/unidirectional-streams.spec.d.ts.map +1 -1
- package/lib/dom.ts +7 -2
- package/lib/event-loop.js +13 -7
- package/lib/server.js +1 -1
- package/lib/session.js +71 -21
- package/lib/stream.js +137 -12
- package/lib/transport.js +3 -1
- package/lib/types.ts +13 -2
- package/lib/webtransport.js +31 -0
- package/package.json +5 -4
- package/platform/base/strings/utf_ostream_operators.h +5 -0
- package/platform/quiche/quic/core/io/socket_win.inc +3 -0
- package/platform/quiche_platform_impl/quiche_command_line_flags_impl.h +7 -0
- package/platform/quiche_platform_impl/quiche_export_impl.h +3 -9
- package/platform/quiche_platform_impl/quiche_server_stats_impl.h +1 -22
- package/platform/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h +1 -4
- package/platform/quiche_platform_impl/quiche_time_utils_impl.h +1 -13
- package/platform/quiche_platform_impl/quiche_udp_socket_platform_impl.h +9 -0
- package/readme.md +3 -1
- package/src/http3client.cc +13 -29
- package/src/http3client.h +2 -6
- package/src/http3clientsession.cc +51 -40
- package/src/http3clientsession.h +44 -31
- package/src/http3clientstream.cc +17 -0
- package/src/http3clientstream.h +10 -0
- package/src/http3eventloop.cc +81 -61
- package/src/http3eventloop.h +10 -7
- package/src/http3server.cc +1 -1
- package/src/http3serversession.cc +1 -136
- package/src/http3serversession.h +7 -77
- package/src/http3serverstream.cc +0 -49
- package/src/http3serverstream.h +0 -5
- package/src/http3wtsessionvisitor.cc +1 -1
- package/src/http3wtsessionvisitor.h +24 -37
- package/src/http3wtstreamvisitor.cc +35 -8
- package/src/http3wtstreamvisitor.h +81 -3
- package/test/bidirectional-streams.spec.js +16 -7
- package/test/datagrams.spec.js +31 -20
- package/test/fixtures/p-timeout.js +33 -0
- package/test/fixtures/read-stream.js +4 -1
- package/test/unidirectional-streams.spec.js +24 -15
- package/platform/net/quiche/common/platform/impl/quiche_flags_impl.h +0 -12
- package/platform/poll.h +0 -2
- package/platform/quiche/quic/core/io/quic_poll_event_loop.h +0 -8
- package/platform/quiche_platform_impl/quic_testvalue_impl.h +0 -19
- package/platform/quiche_platform_impl/quic_udp_socket_winsock.cc +0 -732
- package/platform/quiche_platform_impl/quiche_time_utils_impl.cc +0 -43
- package/platform/quiche_platform_impl/socket_winsock.cc +0 -535
|
@@ -34,14 +34,12 @@ namespace quic
|
|
|
34
34
|
Http3ServerBackend *http3_server_backend)
|
|
35
35
|
: QuicServerSessionBase(config, supported_versions, connection, visitor,
|
|
36
36
|
helper, crypto_config, compressed_certs_cache),
|
|
37
|
-
highest_promised_stream_id_(
|
|
38
|
-
QuicUtils::GetInvalidStreamId(connection->transport_version())),
|
|
39
37
|
http3_server_backend_(http3_server_backend)
|
|
40
38
|
{
|
|
41
39
|
QUICHE_DCHECK(http3_server_backend_);
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
Http3ServerSession::~Http3ServerSession() {
|
|
42
|
+
Http3ServerSession::~Http3ServerSession() { DeleteConnection(); }
|
|
45
43
|
|
|
46
44
|
std::unique_ptr<QuicCryptoServerStreamBase>
|
|
47
45
|
Http3ServerSession::CreateQuicCryptoServerStream(
|
|
@@ -122,137 +120,4 @@ namespace quic
|
|
|
122
120
|
ActivateStream(absl::WrapUnique(stream));
|
|
123
121
|
return stream;
|
|
124
122
|
}
|
|
125
|
-
|
|
126
|
-
void Http3ServerSession::HandleFrameOnNonexistentOutgoingStream(
|
|
127
|
-
QuicStreamId stream_id)
|
|
128
|
-
{
|
|
129
|
-
// If this stream is a promised but not created stream (stream_id within the
|
|
130
|
-
// range of next_outgoing_stream_id_ and highes_promised_stream_id_),
|
|
131
|
-
// connection shouldn't be closed.
|
|
132
|
-
// Otherwise behave in the same way as base class.
|
|
133
|
-
if (highest_promised_stream_id_ ==
|
|
134
|
-
QuicUtils::GetInvalidStreamId(transport_version()) ||
|
|
135
|
-
stream_id > highest_promised_stream_id_)
|
|
136
|
-
{
|
|
137
|
-
QuicSession::HandleFrameOnNonexistentOutgoingStream(stream_id);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
void Http3ServerSession::HandleRstOnValidNonexistentStream(
|
|
142
|
-
const QuicRstStreamFrame &frame)
|
|
143
|
-
{
|
|
144
|
-
QuicSession::HandleRstOnValidNonexistentStream(frame);
|
|
145
|
-
if (!IsClosedStream(frame.stream_id))
|
|
146
|
-
{
|
|
147
|
-
// If a nonexistent stream is not a closed stream and still valid, it must
|
|
148
|
-
// be a locally preserved stream. Resetting this kind of stream means
|
|
149
|
-
// cancelling the promised server push.
|
|
150
|
-
// Since PromisedStreamInfo are queued in sequence, the corresponding
|
|
151
|
-
// index for it in promised_streams_ can be calculated.
|
|
152
|
-
QuicStreamId next_stream_id = next_outgoing_unidirectional_stream_id();
|
|
153
|
-
if ((!version().HasIetfQuicFrames() ||
|
|
154
|
-
!QuicUtils::IsBidirectionalStreamId(frame.stream_id, version())) &&
|
|
155
|
-
frame.stream_id >= next_stream_id)
|
|
156
|
-
{
|
|
157
|
-
size_t index = (frame.stream_id - next_stream_id) /
|
|
158
|
-
QuicUtils::StreamIdDelta(transport_version());
|
|
159
|
-
if (index <= promised_streams_.size())
|
|
160
|
-
{
|
|
161
|
-
promised_streams_[index].is_cancelled = true;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
control_frame_manager().WriteOrBufferRstStream(
|
|
165
|
-
frame.stream_id,
|
|
166
|
-
QuicResetStreamError::FromInternal(QUIC_RST_ACKNOWLEDGEMENT), 0);
|
|
167
|
-
connection()->OnStreamReset(frame.stream_id, QUIC_RST_ACKNOWLEDGEMENT);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/*
|
|
172
|
-
spdy::Http2HeaderBlock Http3ServerSession::SynthesizePushRequestHeaders(
|
|
173
|
-
std::string request_url, QuicBackendResponse::ServerPushInfo resource,
|
|
174
|
-
const spdy::Http2HeaderBlock& original_request_headers) {
|
|
175
|
-
QuicUrl push_request_url = resource.request_url;
|
|
176
|
-
|
|
177
|
-
spdy::Http2HeaderBlock spdy_headers = original_request_headers.Clone();
|
|
178
|
-
// :authority could be different from original request.
|
|
179
|
-
spdy_headers[":authority"] = push_request_url.host();
|
|
180
|
-
spdy_headers[":path"] = push_request_url.path();
|
|
181
|
-
// Push request always use GET.
|
|
182
|
-
spdy_headers[":method"] = "GET";
|
|
183
|
-
spdy_headers["referer"] = request_url;
|
|
184
|
-
spdy_headers[":scheme"] = push_request_url.scheme();
|
|
185
|
-
// It is not possible to push a response to a request that includes a request
|
|
186
|
-
// body.
|
|
187
|
-
spdy_headers["content-length"] = "0";
|
|
188
|
-
// Remove "host" field as push request is a directly generated HTTP2 request
|
|
189
|
-
// which should use ":authority" instead of "host".
|
|
190
|
-
spdy_headers.erase("host");
|
|
191
|
-
return spdy_headers;
|
|
192
|
-
}*/
|
|
193
|
-
|
|
194
|
-
/*
|
|
195
|
-
void Http3ServerSession::SendPushPromise(QuicStreamId original_stream_id,
|
|
196
|
-
QuicStreamId promised_stream_id,
|
|
197
|
-
spdy::Http2HeaderBlock headers) {
|
|
198
|
-
QUIC_DLOG(INFO) << "stream " << original_stream_id
|
|
199
|
-
<< " send PUSH_PROMISE for promised stream "
|
|
200
|
-
<< promised_stream_id;
|
|
201
|
-
WritePushPromise(original_stream_id, promised_stream_id, std::move(headers));
|
|
202
|
-
}*/
|
|
203
|
-
|
|
204
|
-
void Http3ServerSession::HandlePromisedPushRequests()
|
|
205
|
-
{
|
|
206
|
-
while (!promised_streams_.empty() &&
|
|
207
|
-
ShouldCreateOutgoingUnidirectionalStream())
|
|
208
|
-
{
|
|
209
|
-
PromisedStreamInfo &promised_info = promised_streams_.front();
|
|
210
|
-
QUICHE_DCHECK_EQ(next_outgoing_unidirectional_stream_id(),
|
|
211
|
-
promised_info.stream_id);
|
|
212
|
-
|
|
213
|
-
if (promised_info.is_cancelled)
|
|
214
|
-
{
|
|
215
|
-
// This stream has been reset by client. Skip this stream id.
|
|
216
|
-
promised_streams_.pop_front();
|
|
217
|
-
GetNextOutgoingUnidirectionalStreamId();
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
Http3ServerStream *promised_stream =
|
|
222
|
-
static_cast<Http3ServerStream *>(
|
|
223
|
-
CreateOutgoingUnidirectionalStream());
|
|
224
|
-
QUICHE_DCHECK_NE(promised_stream, nullptr);
|
|
225
|
-
QUICHE_DCHECK_EQ(promised_info.stream_id, promised_stream->id());
|
|
226
|
-
QUIC_DLOG(INFO) << "created server push stream " << promised_stream->id();
|
|
227
|
-
|
|
228
|
-
promised_stream->SetPriority(promised_info.priority);
|
|
229
|
-
|
|
230
|
-
spdy::Http2HeaderBlock request_headers(
|
|
231
|
-
std::move(promised_info.request_headers));
|
|
232
|
-
|
|
233
|
-
promised_streams_.pop_front();
|
|
234
|
-
promised_stream->PushResponse(std::move(request_headers));
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
void Http3ServerSession::OnCanCreateNewOutgoingStream(
|
|
239
|
-
bool unidirectional)
|
|
240
|
-
{
|
|
241
|
-
QuicSpdySession::OnCanCreateNewOutgoingStream(unidirectional);
|
|
242
|
-
if (unidirectional)
|
|
243
|
-
{
|
|
244
|
-
HandlePromisedPushRequests();
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
void Http3ServerSession::MaybeInitializeHttp3UnidirectionalStreams()
|
|
249
|
-
{
|
|
250
|
-
size_t previous_static_stream_count = num_static_streams();
|
|
251
|
-
QuicSpdySession::MaybeInitializeHttp3UnidirectionalStreams();
|
|
252
|
-
size_t current_static_stream_count = num_static_streams();
|
|
253
|
-
QUICHE_DCHECK_GE(current_static_stream_count, previous_static_stream_count);
|
|
254
|
-
highest_promised_stream_id_ +=
|
|
255
|
-
QuicUtils::StreamIdDelta(transport_version()) *
|
|
256
|
-
(current_static_stream_count - previous_static_stream_count);
|
|
257
|
-
}
|
|
258
123
|
} // namespace quic
|
package/src/http3serversession.h
CHANGED
|
@@ -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
|
-
|
|
29
|
+
// #include "quic/tools/quic_backend_response.h"
|
|
30
30
|
#include "src/http3serverbackend.h"
|
|
31
31
|
#include "src/http3serverstream.h" // todo
|
|
32
32
|
|
|
@@ -36,25 +36,6 @@ namespace quic
|
|
|
36
36
|
class Http3ServerSession : public QuicServerSessionBase
|
|
37
37
|
{
|
|
38
38
|
public:
|
|
39
|
-
// A PromisedStreamInfo is an element of the queue to store promised
|
|
40
|
-
// stream which hasn't been created yet. It keeps a mapping between promised
|
|
41
|
-
// stream id with its priority and the headers sent out in PUSH_PROMISE.
|
|
42
|
-
struct PromisedStreamInfo
|
|
43
|
-
{
|
|
44
|
-
public:
|
|
45
|
-
PromisedStreamInfo(spdy::Http2HeaderBlock request_headers,
|
|
46
|
-
QuicStreamId stream_id,
|
|
47
|
-
const QuicStreamPriority &priority)
|
|
48
|
-
: request_headers(std::move(request_headers)),
|
|
49
|
-
stream_id(stream_id),
|
|
50
|
-
priority(priority),
|
|
51
|
-
is_cancelled(false) {}
|
|
52
|
-
spdy::Http2HeaderBlock request_headers;
|
|
53
|
-
QuicStreamId stream_id;
|
|
54
|
-
QuicStreamPriority priority;
|
|
55
|
-
bool is_cancelled;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
39
|
// Takes ownership of |connection|.
|
|
59
40
|
Http3ServerSession(const QuicConfig &config,
|
|
60
41
|
const ParsedQuicVersionVector &supported_versions,
|
|
@@ -72,20 +53,12 @@ namespace quic
|
|
|
72
53
|
// Override base class to detact client sending data on server push stream.
|
|
73
54
|
void OnStreamFrame(const QuicStreamFrame &frame) override;
|
|
74
55
|
|
|
75
|
-
void OnCanCreateNewOutgoingStream(bool unidirectional) override;
|
|
76
|
-
|
|
77
|
-
|
|
78
56
|
protected:
|
|
79
57
|
// QuicSession methods:
|
|
80
58
|
QuicSpdyStream *CreateIncomingStream(QuicStreamId id) override;
|
|
81
59
|
QuicSpdyStream *CreateIncomingStream(PendingStream *pending) override;
|
|
82
60
|
QuicSpdyStream *CreateOutgoingBidirectionalStream() override;
|
|
83
61
|
Http3ServerStream *CreateOutgoingUnidirectionalStream() override;
|
|
84
|
-
// Override to return true for locally preserved server push stream.
|
|
85
|
-
void HandleFrameOnNonexistentOutgoingStream(QuicStreamId stream_id) override;
|
|
86
|
-
// Override to handle reseting locally preserved streams.
|
|
87
|
-
void HandleRstOnValidNonexistentStream(
|
|
88
|
-
const QuicRstStreamFrame &frame) override;
|
|
89
62
|
|
|
90
63
|
// QuicServerSessionBaseMethod:
|
|
91
64
|
std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
|
|
@@ -97,12 +70,14 @@ namespace quic
|
|
|
97
70
|
return http3_server_backend_;
|
|
98
71
|
}
|
|
99
72
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
bool ShouldNegotiateWebTransport() override
|
|
73
|
+
WebTransportHttp3VersionSet LocallySupportedWebTransportVersions()
|
|
74
|
+
const override
|
|
103
75
|
{
|
|
104
|
-
return http3_server_backend_->SupportsWebTransport()
|
|
76
|
+
return http3_server_backend_->SupportsWebTransport()
|
|
77
|
+
? kDefaultSupportedWebTransportVersions
|
|
78
|
+
: WebTransportHttp3VersionSet();
|
|
105
79
|
}
|
|
80
|
+
|
|
106
81
|
HttpDatagramSupport LocalHttpDatagramSupport() override
|
|
107
82
|
{
|
|
108
83
|
if (ShouldNegotiateWebTransport())
|
|
@@ -112,51 +87,6 @@ namespace quic
|
|
|
112
87
|
return QuicServerSessionBase::LocalHttpDatagramSupport();
|
|
113
88
|
}
|
|
114
89
|
|
|
115
|
-
private:
|
|
116
|
-
/*friend class test::QuicSimpleServerSessionPeer;
|
|
117
|
-
|
|
118
|
-
// Create a server push headers block by copying request's headers block.
|
|
119
|
-
// But replace or add these pseudo-headers as they are specific to each
|
|
120
|
-
// request:
|
|
121
|
-
// :authority, :path, :method, :scheme, referer.
|
|
122
|
-
// Copying the rest headers ensures they are the same as the original
|
|
123
|
-
// request, especially cookies.
|
|
124
|
-
spdy::Http2HeaderBlock SynthesizePushRequestHeaders(
|
|
125
|
-
std::string request_url,
|
|
126
|
-
QuicBackendResponse::ServerPushInfo resource,
|
|
127
|
-
const spdy::Http2HeaderBlock& original_request_headers);
|
|
128
|
-
|
|
129
|
-
// Send PUSH_PROMISE frame on headers stream.
|
|
130
|
-
void SendPushPromise(QuicStreamId original_stream_id,
|
|
131
|
-
QuicStreamId promised_stream_id,
|
|
132
|
-
spdy::Http2HeaderBlock headers);
|
|
133
|
-
|
|
134
|
-
// Fetch response from cache for request headers enqueued into
|
|
135
|
-
// promised_headers_and_streams_ and send them on dedicated stream until
|
|
136
|
-
// reaches max_open_stream_ limit.
|
|
137
|
-
// Called when return value of GetNumOpenOutgoingStreams() changes:
|
|
138
|
-
// CloseStreamInner();
|
|
139
|
-
// StreamDraining();
|
|
140
|
-
// Note that updateFlowControlOnFinalReceivedByteOffset() won't change the
|
|
141
|
-
// return value becasue all push streams are impossible to become locally
|
|
142
|
-
// closed. Since a locally preserved stream becomes remotely closed after
|
|
143
|
-
// HandlePromisedPushRequests() starts to process it, and if it is reset
|
|
144
|
-
// locally afterwards, it will be immediately become closed and never get into
|
|
145
|
-
// locally_closed_stream_highest_offset_. So all the streams in this map
|
|
146
|
-
// are not outgoing streams.*/
|
|
147
|
-
void HandlePromisedPushRequests();
|
|
148
|
-
|
|
149
|
-
// Keep track of the highest stream id which has been sent in PUSH_PROMISE.
|
|
150
|
-
QuicStreamId highest_promised_stream_id_;
|
|
151
|
-
|
|
152
|
-
// Promised streams which hasn't been created yet because of max_open_stream_
|
|
153
|
-
// limit. New element is added to the end of the queue.
|
|
154
|
-
// Since outgoing stream is created in sequence, stream_id of each element in
|
|
155
|
-
// the queue also increases by 2 from previous one's. The front element's
|
|
156
|
-
// stream_id is always next_outgoing_stream_id_, and the last one is always
|
|
157
|
-
// highest_promised_stream_id_.
|
|
158
|
-
quiche::QuicheCircularDeque<PromisedStreamInfo> promised_streams_;
|
|
159
|
-
|
|
160
90
|
Http3ServerBackend *http3_server_backend_; // Not owned.
|
|
161
91
|
};
|
|
162
92
|
|
package/src/http3serverstream.cc
CHANGED
|
@@ -149,27 +149,6 @@ namespace quic
|
|
|
149
149
|
SendResponse();
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
void Http3ServerStream::PushResponse(
|
|
153
|
-
Http2HeaderBlock push_request_headers)
|
|
154
|
-
{
|
|
155
|
-
if (QuicUtils::IsClientInitiatedStreamId(session()->transport_version(),
|
|
156
|
-
id()))
|
|
157
|
-
{
|
|
158
|
-
QUIC_BUG(quic_bug_10962_2)
|
|
159
|
-
<< "Client initiated stream shouldn't be used as promised stream.";
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
// Change the stream state to emulate a client request.
|
|
163
|
-
request_headers_ = std::move(push_request_headers);
|
|
164
|
-
content_length_ = 0;
|
|
165
|
-
QUIC_DVLOG(1) << "Stream " << id()
|
|
166
|
-
<< " ready to receive server push response.";
|
|
167
|
-
QUICHE_DCHECK(reading_stopped());
|
|
168
|
-
|
|
169
|
-
// Directly send response based on the emulated request_headers_.
|
|
170
|
-
SendResponse();
|
|
171
|
-
}
|
|
172
|
-
|
|
173
152
|
void Http3ServerStream::SendResponse()
|
|
174
153
|
{
|
|
175
154
|
if (request_headers_.empty())
|
|
@@ -250,19 +229,7 @@ namespace quic
|
|
|
250
229
|
// http3_server_backend_->FetchResponseFromBackend(request_headers_, body_,
|
|
251
230
|
// this);
|
|
252
231
|
}
|
|
253
|
-
/*
|
|
254
|
-
QuicConnectionId Http3ServerStream::connection_id() const {
|
|
255
|
-
return spdy_session()->connection_id();
|
|
256
|
-
}
|
|
257
232
|
|
|
258
|
-
QuicStreamId Http3ServerStream::stream_id() const {
|
|
259
|
-
return id();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
std::string Http3ServerStream::peer_host() const {
|
|
263
|
-
return spdy_session()->peer_address().host().ToString();
|
|
264
|
-
}
|
|
265
|
-
*/
|
|
266
233
|
void Http3ServerStream::OnResponseBackendComplete(
|
|
267
234
|
const Http3BackendResponse *response)
|
|
268
235
|
{
|
|
@@ -330,22 +297,6 @@ namespace quic
|
|
|
330
297
|
return;
|
|
331
298
|
}
|
|
332
299
|
|
|
333
|
-
if (QuicUtils::IsServerInitiatedStreamId(session()->transport_version(),
|
|
334
|
-
id()))
|
|
335
|
-
{
|
|
336
|
-
// A server initiated stream is only used for a server push response,
|
|
337
|
-
// and only 200 and 30X response codes are supported for server push.
|
|
338
|
-
// This behavior mirrors the HTTP/2 implementation.
|
|
339
|
-
bool is_redirection = response_code / 100 == 3;
|
|
340
|
-
if (response_code != 200 && !is_redirection)
|
|
341
|
-
{
|
|
342
|
-
QUIC_LOG(WARNING) << "Response to server push request " << request_url
|
|
343
|
-
<< " result in response code " << response_code;
|
|
344
|
-
Reset(QUIC_STREAM_CANCELLED);
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
300
|
if (response->response_type() == Http3BackendResponse::INCOMPLETE_RESPONSE)
|
|
350
301
|
{
|
|
351
302
|
QUIC_DVLOG(1)
|
package/src/http3serverstream.h
CHANGED
|
@@ -53,11 +53,6 @@ namespace quic
|
|
|
53
53
|
|
|
54
54
|
void OnInvalidHeaders() override;
|
|
55
55
|
|
|
56
|
-
// Make this stream start from as if it just finished parsing an incoming
|
|
57
|
-
// request whose headers are equivalent to |push_request_headers|.
|
|
58
|
-
// Doing so will trigger this toy stream to fetch response and send it back.
|
|
59
|
-
virtual void PushResponse(spdy::Http2HeaderBlock push_request_headers);
|
|
60
|
-
|
|
61
56
|
// The response body of error responses.
|
|
62
57
|
static const char *const kErrorResponseBody;
|
|
63
58
|
static const char *const kNotFoundResponseBody;
|
|
@@ -25,7 +25,7 @@ namespace quic
|
|
|
25
25
|
session_->eventloop_->informSessionClosed(session_, error_code, error_message);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
void Http3WTSession::Visitor::OnSessionReady(
|
|
28
|
+
void Http3WTSession::Visitor::OnSessionReady()
|
|
29
29
|
{
|
|
30
30
|
session_->eventloop_->informSessionReady(session_);
|
|
31
31
|
|
|
@@ -52,7 +52,11 @@ namespace quic
|
|
|
52
52
|
{
|
|
53
53
|
session_ = session;
|
|
54
54
|
eventloop_ = eventloop;
|
|
55
|
-
|
|
55
|
+
if (session_) {
|
|
56
|
+
session_->SetOnDraining([this]() {
|
|
57
|
+
eventloop_->informGoawayReceived(this);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
class Visitor : public WebTransportVisitor
|
|
@@ -62,7 +66,7 @@ namespace quic
|
|
|
62
66
|
|
|
63
67
|
~Visitor();
|
|
64
68
|
|
|
65
|
-
void OnSessionReady(
|
|
69
|
+
void OnSessionReady() override;
|
|
66
70
|
|
|
67
71
|
void OnSessionClosed(WebTransportSessionError error_code,
|
|
68
72
|
const std::string &error_message) override;
|
|
@@ -219,6 +223,13 @@ namespace quic
|
|
|
219
223
|
eventloop_->Schedule(task);
|
|
220
224
|
}
|
|
221
225
|
|
|
226
|
+
void notifySessionDrainingInt()
|
|
227
|
+
{
|
|
228
|
+
std::function<void()> task = [this]()
|
|
229
|
+
{ if (session_) session_->NotifySessionDraining(); };
|
|
230
|
+
eventloop_->Schedule(task);
|
|
231
|
+
}
|
|
232
|
+
|
|
222
233
|
void closeInt(int code, std::string &reason)
|
|
223
234
|
{
|
|
224
235
|
std::function<void()> task = [this, code, reason]()
|
|
@@ -226,49 +237,18 @@ namespace quic
|
|
|
226
237
|
eventloop_->Schedule(task);
|
|
227
238
|
}
|
|
228
239
|
|
|
229
|
-
class DatagramAllocator : public quiche::QuicheBufferAllocator
|
|
230
|
-
{
|
|
231
|
-
public:
|
|
232
|
-
DatagramAllocator(Http3EventLoop *eventloop) : eventloop_(eventloop)
|
|
233
|
-
{
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
char *New(size_t size) { return nullptr; } // fake it comes from javascript
|
|
237
|
-
char *New(size_t size, bool flag_enable) { return nullptr; } // fake it comes from javascript
|
|
238
|
-
|
|
239
|
-
void Delete(char *buffer)
|
|
240
|
-
{
|
|
241
|
-
eventloop_->informDatagramBufferFree(buffers_[buffer]);
|
|
242
|
-
buffers_.erase(buffer);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
void registerBuffer(char *buffer, Napi::ObjectReference *bufferhandle)
|
|
246
|
-
{
|
|
247
|
-
buffers_[buffer] = bufferhandle;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
protected:
|
|
251
|
-
Http3EventLoop *eventloop_;
|
|
252
|
-
std::map<char *, Napi::ObjectReference *> buffers_;
|
|
253
|
-
};
|
|
254
|
-
|
|
255
240
|
void writeDatagramInt(char *buffer, size_t len, Napi::ObjectReference *bufferhandle)
|
|
256
241
|
{
|
|
257
242
|
if (!session_)
|
|
258
243
|
{
|
|
259
|
-
eventloop_->informDatagramSend(this);
|
|
244
|
+
eventloop_->informDatagramSend(this, bufferhandle);
|
|
260
245
|
return;
|
|
261
246
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
quiche::QuicheBufferDeleter(allocator_.get()));
|
|
265
|
-
|
|
266
|
-
quiche::QuicheMemSlice slice(quiche::QuicheBuffer(std::move(ubuffer), len));
|
|
267
|
-
session_->SendOrQueueDatagram(std::move(slice));
|
|
268
|
-
eventloop_->informDatagramSend(this);
|
|
247
|
+
session_->SendOrQueueDatagram(absl::string_view(buffer, len));
|
|
248
|
+
eventloop_->informDatagramSend(this, bufferhandle);
|
|
269
249
|
}
|
|
250
|
+
|
|
270
251
|
WebTransportSession *session_;
|
|
271
|
-
std::unique_ptr<DatagramAllocator> allocator_;
|
|
272
252
|
bool echo_stream_opened_ = false;
|
|
273
253
|
Http3EventLoop *eventloop_;
|
|
274
254
|
uint32_t ordBidiStreams;
|
|
@@ -315,6 +295,11 @@ namespace quic
|
|
|
315
295
|
}
|
|
316
296
|
}
|
|
317
297
|
|
|
298
|
+
void notifySessionDraining(const Napi::CallbackInfo &info)
|
|
299
|
+
{
|
|
300
|
+
wtsession_->notifySessionDrainingInt();
|
|
301
|
+
}
|
|
302
|
+
|
|
318
303
|
void close(const Napi::CallbackInfo &info)
|
|
319
304
|
{
|
|
320
305
|
int code = 0;
|
|
@@ -351,6 +336,8 @@ namespace quic
|
|
|
351
336
|
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
352
337
|
InstanceMethod<&Http3WTSessionJS::writeDatagram>("writeDatagram",
|
|
353
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)),
|
|
354
341
|
InstanceMethod<&Http3WTSessionJS::close>("close",
|
|
355
342
|
static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
|
|
356
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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()
|