@fails-components/webtransport 0.3.1 → 1.0.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/lib/client.js +81 -40
- package/lib/dom.ts +7 -5
- package/lib/http2/browser/browser.js +168 -0
- package/lib/http2/browser/browserparser.js +248 -0
- package/lib/http2/flowcontroller.js +371 -0
- package/lib/http2/node/capsuleparser.js +291 -0
- package/lib/http2/node/client.js +239 -0
- package/lib/http2/node/index.js +2 -0
- package/lib/http2/node/server.js +499 -0
- package/lib/http2/node/websocketparser.js +829 -0
- package/lib/http2/parserbase.js +139 -0
- package/lib/http2/parserbasehttp2.js +128 -0
- package/lib/http2/session.js +225 -0
- package/lib/http2/stream.js +354 -0
- package/lib/http2/websocketcommon.js +1 -0
- package/lib/{index.js → index.browser.js} +6 -10
- package/lib/index.node.js +27 -0
- package/lib/server.js +252 -69
- package/lib/session.js +31 -68
- package/lib/stream.js +103 -179
- package/lib/types.ts +174 -87
- package/lib/utils.js +2 -1
- package/lib/webstreams.browser.js +6 -0
- package/lib/webstreams.js +7 -0
- package/lib/webtransport.browser.js +284 -0
- package/lib/webtransport.node.js +137 -0
- package/lib/{webtransport.js → webtransportbase.js} +47 -41
- package/old_test/test.js +31 -29
- package/old_test/testsuite.js +1 -1
- package/package.json +18 -17
- package/readme.md +94 -30
- package/test/bidirectional-streams.spec.js +51 -9
- package/test/datagrams.spec.js +8 -2
- package/test/fixtures/known-bytes.js +29 -0
- package/test/fixtures/read-stream.js +1 -1
- package/test/fixtures/reader-value.js +1 -1
- package/test/fixtures/server.js +24 -10
- package/test/fixtures/webtransport.browser.js +20 -2
- package/test/fixtures/webtransport.js +1 -1
- package/test/index.js +33 -6
- package/test/pw-no-https-errors.json +5 -0
- package/test/session.spec.js +71 -52
- package/test/unidirectional-streams.spec.js +20 -4
- package/CMakeLists.txt +0 -991
- package/LICENSE.chromium +0 -27
- package/LICENSE.envoy +0 -207
- package/build.js +0 -313
- package/dist/lib/client.d.ts +0 -78
- package/dist/lib/client.d.ts.map +0 -1
- package/dist/lib/dom.d.ts +0 -87
- package/dist/lib/dom.d.ts.map +0 -1
- package/dist/lib/error.d.ts +0 -8
- package/dist/lib/error.d.ts.map +0 -1
- package/dist/lib/event-loop.d.ts +0 -33
- package/dist/lib/event-loop.d.ts.map +0 -1
- package/dist/lib/index.d.ts +0 -79
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/native.d.ts +0 -2
- package/dist/lib/native.d.ts.map +0 -1
- package/dist/lib/server.d.ts +0 -92
- package/dist/lib/server.d.ts.map +0 -1
- package/dist/lib/session.d.ts +0 -298
- package/dist/lib/session.d.ts.map +0 -1
- package/dist/lib/stream.d.ts +0 -135
- package/dist/lib/stream.d.ts.map +0 -1
- package/dist/lib/transport.d.ts +0 -34
- package/dist/lib/transport.d.ts.map +0 -1
- package/dist/lib/types.d.ts +0 -212
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/utils.d.ts +0 -11
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/webtransport.d.ts +0 -47
- package/dist/lib/webtransport.d.ts.map +0 -1
- package/dist/test/bidirectional-streams.spec.d.ts +0 -5
- package/dist/test/bidirectional-streams.spec.d.ts.map +0 -1
- package/dist/test/datagrams.spec.d.ts +0 -5
- package/dist/test/datagrams.spec.d.ts.map +0 -1
- package/dist/test/event-loop.node.d.ts +0 -2
- package/dist/test/event-loop.node.d.ts.map +0 -1
- package/dist/test/fixtures/certificate.d.ts +0 -21
- package/dist/test/fixtures/certificate.d.ts.map +0 -1
- package/dist/test/fixtures/chai.d.ts +0 -2
- package/dist/test/fixtures/chai.d.ts.map +0 -1
- package/dist/test/fixtures/known-bytes.d.ts +0 -6
- package/dist/test/fixtures/known-bytes.d.ts.map +0 -1
- package/dist/test/fixtures/p-timeout.d.ts +0 -8
- package/dist/test/fixtures/p-timeout.d.ts.map +0 -1
- package/dist/test/fixtures/read-cert-hash.d.ts +0 -6
- package/dist/test/fixtures/read-cert-hash.d.ts.map +0 -1
- package/dist/test/fixtures/read-stream.d.ts +0 -19
- package/dist/test/fixtures/read-stream.d.ts.map +0 -1
- package/dist/test/fixtures/reader-value.d.ts +0 -22
- package/dist/test/fixtures/reader-value.d.ts.map +0 -1
- package/dist/test/fixtures/server.d.ts +0 -5
- package/dist/test/fixtures/server.d.ts.map +0 -1
- package/dist/test/fixtures/webtransport.browser.d.ts +0 -3
- package/dist/test/fixtures/webtransport.browser.d.ts.map +0 -1
- package/dist/test/fixtures/webtransport.d.ts +0 -3
- package/dist/test/fixtures/webtransport.d.ts.map +0 -1
- package/dist/test/fixtures/write-stream.d.ts +0 -10
- package/dist/test/fixtures/write-stream.d.ts.map +0 -1
- package/dist/test/index.d.ts +0 -2
- package/dist/test/index.d.ts.map +0 -1
- package/dist/test/session.spec.d.ts +0 -5
- package/dist/test/session.spec.d.ts.map +0 -1
- package/dist/test/unidirectional-streams.spec.d.ts +0 -2
- package/dist/test/unidirectional-streams.spec.d.ts.map +0 -1
- package/failslogolicensereadme.txt +0 -4
- package/lib/event-loop.js +0 -88
- package/lib/native.js +0 -28
- package/lib/transport.js +0 -82
- package/platform/icufix/fakedata.cpp +0 -8
- package/platform/quiche/quic/core/io/socket_win.inc +0 -3
- package/platform/quiche_platform_impl/quiche_bug_tracker_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_client_stats_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_command_line_flags_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_containers_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_event_loop_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_export_impl.h +0 -6
- package/platform/quiche_platform_impl/quiche_flag_utils_impl.h +0 -11
- package/platform/quiche_platform_impl/quiche_flags_impl.h +0 -8
- package/platform/quiche_platform_impl/quiche_iovec_impl.h +0 -10
- package/platform/quiche_platform_impl/quiche_logging_impl.h +0 -21
- package/platform/quiche_platform_impl/quiche_mem_slice_impl.h +0 -2
- package/platform/quiche_platform_impl/quiche_mutex_impl.h +0 -8
- package/platform/quiche_platform_impl/quiche_prefetch_impl.h +0 -11
- package/platform/quiche_platform_impl/quiche_reference_counted_impl.h +0 -16
- package/platform/quiche_platform_impl/quiche_server_stats_impl.h +0 -7
- package/platform/quiche_platform_impl/quiche_stack_trace_impl.h +0 -12
- package/platform/quiche_platform_impl/quiche_stream_buffer_allocator_impl.h +0 -8
- package/platform/quiche_platform_impl/quiche_testvalue_impl.h +0 -1
- package/platform/quiche_platform_impl/quiche_thread_local_impl.h +0 -6
- package/platform/quiche_platform_impl/quiche_time_utils_impl.h +0 -13
- package/platform/quiche_platform_impl/quiche_udp_socket_platform_impl.h +0 -39
- package/src/http3backendresponse.cc +0 -36
- package/src/http3backendresponse.h +0 -109
- package/src/http3client.cc +0 -1529
- package/src/http3client.h +0 -557
- package/src/http3clientsession.cc +0 -65
- package/src/http3clientsession.h +0 -60
- package/src/http3clientstream.cc +0 -52
- package/src/http3clientstream.h +0 -42
- package/src/http3dispatcher.cc +0 -62
- package/src/http3dispatcher.h +0 -57
- package/src/http3eventloop.cc +0 -1107
- package/src/http3eventloop.h +0 -316
- package/src/http3server.cc +0 -514
- package/src/http3server.h +0 -151
- package/src/http3serverbackend.cc +0 -105
- package/src/http3serverbackend.h +0 -98
- package/src/http3serversession.cc +0 -123
- package/src/http3serversession.h +0 -95
- package/src/http3serverstream.cc +0 -463
- package/src/http3serverstream.h +0 -114
- package/src/http3sessioncache.cc +0 -85
- package/src/http3sessioncache.h +0 -59
- package/src/http3wtsessionvisitor.cc +0 -46
- package/src/http3wtsessionvisitor.h +0 -397
- package/src/http3wtstreamvisitor.cc +0 -155
- package/src/http3wtstreamvisitor.h +0 -404
- package/test/event-loop.node.js +0 -24
- package/tsconfig.json +0 -39
package/src/http3serverstream.cc
DELETED
|
@@ -1,463 +0,0 @@
|
|
|
1
|
-
// modifications
|
|
2
|
-
// Copyright (c) 2022 Marten Richter or other contributers (see commit). All rights reserved.
|
|
3
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
4
|
-
// found in the LICENSE file.
|
|
5
|
-
|
|
6
|
-
// original copyright, see LICENSE.chromium
|
|
7
|
-
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
8
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
9
|
-
// found in the LICENSE file.
|
|
10
|
-
|
|
11
|
-
#include "src/http3serverstream.h"
|
|
12
|
-
|
|
13
|
-
#include <list>
|
|
14
|
-
#include <utility>
|
|
15
|
-
|
|
16
|
-
#include "absl/strings/match.h"
|
|
17
|
-
#include "absl/strings/numbers.h"
|
|
18
|
-
#include "absl/strings/str_cat.h"
|
|
19
|
-
#include "absl/strings/string_view.h"
|
|
20
|
-
#include "quiche/quic/core/http/quic_spdy_stream.h"
|
|
21
|
-
#include "quiche/quic/core/http/spdy_utils.h"
|
|
22
|
-
#include "quiche/quic/core/http/web_transport_http3.h"
|
|
23
|
-
#include "quiche/quic/core/quic_utils.h"
|
|
24
|
-
#include "quiche/quic/platform/api/quic_bug_tracker.h"
|
|
25
|
-
#include "quiche/quic/platform/api/quic_flags.h"
|
|
26
|
-
#include "quiche/quic/platform/api/quic_logging.h"
|
|
27
|
-
#include "src/http3serversession.h"
|
|
28
|
-
#include "quiche/spdy/core/spdy_protocol.h"
|
|
29
|
-
|
|
30
|
-
using spdy::Http2HeaderBlock;
|
|
31
|
-
|
|
32
|
-
namespace quic
|
|
33
|
-
{
|
|
34
|
-
|
|
35
|
-
Http3ServerStream::Http3ServerStream(
|
|
36
|
-
QuicStreamId id,
|
|
37
|
-
QuicSpdySession *session,
|
|
38
|
-
StreamType type,
|
|
39
|
-
Http3ServerBackend *http3_server_backend)
|
|
40
|
-
: QuicSpdyServerStreamBase(id, session, type),
|
|
41
|
-
content_length_(-1),
|
|
42
|
-
generate_bytes_length_(0),
|
|
43
|
-
http3_server_backend_(http3_server_backend)
|
|
44
|
-
{
|
|
45
|
-
QUICHE_DCHECK(http3_server_backend_);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
Http3ServerStream::Http3ServerStream(
|
|
49
|
-
PendingStream *pending, QuicSpdySession *session,
|
|
50
|
-
Http3ServerBackend *http3_server_backend)
|
|
51
|
-
: QuicSpdyServerStreamBase(pending, session),
|
|
52
|
-
content_length_(-1),
|
|
53
|
-
generate_bytes_length_(0),
|
|
54
|
-
http3_server_backend_(http3_server_backend)
|
|
55
|
-
{
|
|
56
|
-
QUICHE_DCHECK(http3_server_backend_);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
Http3ServerStream::~Http3ServerStream()
|
|
60
|
-
{
|
|
61
|
-
// http3_server_backend_->CloseBackendResponseStream(this);
|
|
62
|
-
for (auto prom : pending_proms_)
|
|
63
|
-
{
|
|
64
|
-
std::unique_ptr<Http3ServerBackend::WebTransportResponse> response =
|
|
65
|
-
std::make_unique<Http3ServerBackend::WebTransportResponse>();
|
|
66
|
-
response->response_headers[":status"] = "500"; // internal server error, probably implementation on js side
|
|
67
|
-
prom->resolve(std::move(response));
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
void Http3ServerStream::OnInitialHeadersComplete(
|
|
72
|
-
bool fin,
|
|
73
|
-
size_t frame_len,
|
|
74
|
-
const QuicHeaderList &header_list)
|
|
75
|
-
{
|
|
76
|
-
QuicSpdyStream::OnInitialHeadersComplete(fin, frame_len, header_list);
|
|
77
|
-
// QuicSpdyStream::OnInitialHeadersComplete() may have already sent error
|
|
78
|
-
// response.
|
|
79
|
-
if (!response_sent_ &&
|
|
80
|
-
!SpdyUtils::CopyAndValidateHeaders(header_list, &content_length_,
|
|
81
|
-
&request_headers_))
|
|
82
|
-
{
|
|
83
|
-
QUIC_DVLOG(1) << "Invalid headers";
|
|
84
|
-
SendErrorResponse();
|
|
85
|
-
}
|
|
86
|
-
ConsumeHeaderList();
|
|
87
|
-
if (!fin && !response_sent_)
|
|
88
|
-
{
|
|
89
|
-
// CONNECT and other CONNECT-like methods (such as CONNECT-UDP) require
|
|
90
|
-
// sending the response right after parsing the headers even though the FIN
|
|
91
|
-
// bit has not been received on the request stream.
|
|
92
|
-
auto it = request_headers_.find(":method");
|
|
93
|
-
if (it != request_headers_.end() &&
|
|
94
|
-
absl::StartsWith(it->second, "CONNECT"))
|
|
95
|
-
{
|
|
96
|
-
SendResponse();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
void Http3ServerStream::OnTrailingHeadersComplete(
|
|
102
|
-
bool /*fin*/,
|
|
103
|
-
size_t /*frame_len*/,
|
|
104
|
-
const QuicHeaderList & /*header_list*/)
|
|
105
|
-
{
|
|
106
|
-
QUIC_BUG(quic_bug_10962_1) << "Server does not support receiving Trailers.";
|
|
107
|
-
SendErrorResponse();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
void Http3ServerStream::OnBodyAvailable()
|
|
111
|
-
{
|
|
112
|
-
while (HasBytesToRead())
|
|
113
|
-
{
|
|
114
|
-
struct iovec iov;
|
|
115
|
-
if (GetReadableRegions(&iov, 1) == 0)
|
|
116
|
-
{
|
|
117
|
-
// No more data to read.
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
QUIC_DVLOG(1) << "Stream " << id() << " processed " << iov.iov_len
|
|
121
|
-
<< " bytes.";
|
|
122
|
-
body_.append(static_cast<char *>(iov.iov_base), iov.iov_len);
|
|
123
|
-
|
|
124
|
-
if (content_length_ >= 0 &&
|
|
125
|
-
body_.size() > static_cast<uint64_t>(content_length_))
|
|
126
|
-
{
|
|
127
|
-
QUIC_DVLOG(1) << "Body size (" << body_.size() << ") > content length ("
|
|
128
|
-
<< content_length_ << ").";
|
|
129
|
-
SendErrorResponse();
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
MarkConsumed(iov.iov_len);
|
|
133
|
-
}
|
|
134
|
-
if (!sequencer()->IsClosed())
|
|
135
|
-
{
|
|
136
|
-
sequencer()->SetUnblocked();
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// If the sequencer is closed, then all the body, including the fin, has been
|
|
141
|
-
// consumed.
|
|
142
|
-
OnFinRead();
|
|
143
|
-
|
|
144
|
-
if (write_side_closed() || fin_buffered())
|
|
145
|
-
{
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
SendResponse();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
void Http3ServerStream::SendResponse()
|
|
153
|
-
{
|
|
154
|
-
if (request_headers_.empty())
|
|
155
|
-
{
|
|
156
|
-
QUIC_DVLOG(1) << "Request headers empty.";
|
|
157
|
-
SendErrorResponse();
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (content_length_ > 0 &&
|
|
162
|
-
static_cast<uint64_t>(content_length_) != body_.size())
|
|
163
|
-
{
|
|
164
|
-
QUIC_DVLOG(1) << "Content length (" << content_length_ << ") != body size ("
|
|
165
|
-
<< body_.size() << ").";
|
|
166
|
-
SendErrorResponse();
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (!request_headers_.contains(":authority"))
|
|
171
|
-
{
|
|
172
|
-
QUIC_DVLOG(1) << "Request headers do not contain :authority.";
|
|
173
|
-
SendErrorResponse();
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (!request_headers_.contains(":path"))
|
|
178
|
-
{
|
|
179
|
-
// CONNECT and other CONNECT-like methods (such as CONNECT-UDP) do not all
|
|
180
|
-
// require :path to be present.
|
|
181
|
-
auto it = request_headers_.find(":method");
|
|
182
|
-
if (it == request_headers_.end() ||
|
|
183
|
-
!absl::StartsWith(it->second, "CONNECT"))
|
|
184
|
-
{
|
|
185
|
-
QUIC_DVLOG(1) << "Request headers do not contain :path.";
|
|
186
|
-
SendErrorResponse();
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (http3_server_backend_ == nullptr)
|
|
192
|
-
{
|
|
193
|
-
QUIC_DVLOG(1) << "Backend is missing.";
|
|
194
|
-
SendErrorResponse();
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (web_transport() != nullptr)
|
|
199
|
-
{
|
|
200
|
-
// to do synchronize lifetime of object, so maybe store promises
|
|
201
|
-
Http3ServerBackend::WebTransportRespPromisePtr response =
|
|
202
|
-
http3_server_backend_->ProcessWebTransportRequest(
|
|
203
|
-
request_headers_, web_transport());
|
|
204
|
-
pending_proms_.insert(response);
|
|
205
|
-
response->finally([this, response](Http3ServerBackend::WebTransportResponse *resp)
|
|
206
|
-
{
|
|
207
|
-
pending_proms_.erase(response);
|
|
208
|
-
if (resp->response_headers[":status"] == "200")
|
|
209
|
-
{
|
|
210
|
-
WriteHeaders(std::move(resp->response_headers), false, nullptr);
|
|
211
|
-
if (resp->visitor != nullptr)
|
|
212
|
-
{
|
|
213
|
-
web_transport()->SetVisitor(std::move(resp->visitor));
|
|
214
|
-
}
|
|
215
|
-
web_transport()->HeadersReceived(request_headers_);
|
|
216
|
-
}
|
|
217
|
-
else
|
|
218
|
-
{
|
|
219
|
-
WriteHeaders(std::move(resp->response_headers), true, nullptr);
|
|
220
|
-
}
|
|
221
|
-
return; });
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Fetch the response from the backend interface and wait for callback once
|
|
226
|
-
// response is ready
|
|
227
|
-
// skip backend
|
|
228
|
-
OnResponseBackendComplete(nullptr);
|
|
229
|
-
// http3_server_backend_->FetchResponseFromBackend(request_headers_, body_,
|
|
230
|
-
// this);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
void Http3ServerStream::OnResponseBackendComplete(
|
|
234
|
-
const Http3BackendResponse *response)
|
|
235
|
-
{
|
|
236
|
-
if (response == nullptr)
|
|
237
|
-
{
|
|
238
|
-
QUIC_DVLOG(1) << "Response not found in cache.";
|
|
239
|
-
SendNotFoundResponse();
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Send Early Hints first.
|
|
244
|
-
for (const auto &headers : response->early_hints())
|
|
245
|
-
{
|
|
246
|
-
QUIC_DVLOG(1) << "Stream " << id() << " sending an Early Hints response: "
|
|
247
|
-
<< headers.DebugString();
|
|
248
|
-
WriteHeaders(headers.Clone(), false, nullptr);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
if (response->response_type() == Http3BackendResponse::CLOSE_CONNECTION)
|
|
252
|
-
{
|
|
253
|
-
QUIC_DVLOG(1) << "Special response: closing connection.";
|
|
254
|
-
OnUnrecoverableError(QUIC_NO_ERROR, "Toy server forcing close");
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (response->response_type() == Http3BackendResponse::IGNORE_REQUEST)
|
|
259
|
-
{
|
|
260
|
-
QUIC_DVLOG(1) << "Special response: ignoring request.";
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (response->response_type() == Http3BackendResponse::BACKEND_ERR_RESPONSE)
|
|
265
|
-
{
|
|
266
|
-
QUIC_DVLOG(1) << "Quic Proxy: Backend connection error.";
|
|
267
|
-
/*502 Bad Gateway
|
|
268
|
-
The server was acting as a gateway or proxy and received an
|
|
269
|
-
invalid response from the upstream server.*/
|
|
270
|
-
SendErrorResponse(502);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Examing response status, if it was not pure integer as typical h2
|
|
275
|
-
// response status, send error response. Notice that
|
|
276
|
-
// QuicHttpResponseCache push urls are strictly authority + path only,
|
|
277
|
-
// scheme is not included (see |QuicHttpResponseCache::GetKey()|).
|
|
278
|
-
std::string request_url = request_headers_[":authority"].as_string() +
|
|
279
|
-
request_headers_[":path"].as_string();
|
|
280
|
-
int response_code;
|
|
281
|
-
const Http2HeaderBlock &response_headers = response->headers();
|
|
282
|
-
if (!ParseHeaderStatusCode(response_headers, &response_code))
|
|
283
|
-
{
|
|
284
|
-
auto status = response_headers.find(":status");
|
|
285
|
-
if (status == response_headers.end())
|
|
286
|
-
{
|
|
287
|
-
QUIC_LOG(WARNING)
|
|
288
|
-
<< ":status not present in response from cache for request "
|
|
289
|
-
<< request_url;
|
|
290
|
-
}
|
|
291
|
-
else
|
|
292
|
-
{
|
|
293
|
-
QUIC_LOG(WARNING) << "Illegal (non-integer) response :status from cache: "
|
|
294
|
-
<< status->second << " for request " << request_url;
|
|
295
|
-
}
|
|
296
|
-
SendErrorResponse();
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (response->response_type() == Http3BackendResponse::INCOMPLETE_RESPONSE)
|
|
301
|
-
{
|
|
302
|
-
QUIC_DVLOG(1)
|
|
303
|
-
<< "Stream " << id()
|
|
304
|
-
<< " sending an incomplete response, i.e. no trailer, no fin.";
|
|
305
|
-
SendIncompleteResponse(response->headers().Clone(), response->body());
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
if (response->response_type() == Http3BackendResponse::GENERATE_BYTES)
|
|
310
|
-
{
|
|
311
|
-
QUIC_DVLOG(1) << "Stream " << id() << " sending a generate bytes response.";
|
|
312
|
-
std::string path = request_headers_[":path"].as_string().substr(1);
|
|
313
|
-
if (!absl::SimpleAtoi(path, &generate_bytes_length_))
|
|
314
|
-
{
|
|
315
|
-
QUIC_LOG(ERROR) << "Path is not a number.";
|
|
316
|
-
SendNotFoundResponse();
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
Http2HeaderBlock headers = response->headers().Clone();
|
|
320
|
-
headers["content-length"] = absl::StrCat(generate_bytes_length_);
|
|
321
|
-
|
|
322
|
-
WriteHeaders(std::move(headers), false, nullptr);
|
|
323
|
-
QUICHE_DCHECK(!response_sent_);
|
|
324
|
-
response_sent_ = true;
|
|
325
|
-
|
|
326
|
-
WriteGeneratedBytes();
|
|
327
|
-
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
QUIC_DVLOG(1) << "Stream " << id() << " sending response.";
|
|
332
|
-
SendHeadersAndBodyAndTrailers(response->headers().Clone(), response->body(),
|
|
333
|
-
response->trailers().Clone());
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
void Http3ServerStream::OnCanWrite()
|
|
337
|
-
{
|
|
338
|
-
QuicSpdyStream::OnCanWrite();
|
|
339
|
-
WriteGeneratedBytes();
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
void Http3ServerStream::WriteGeneratedBytes()
|
|
343
|
-
{
|
|
344
|
-
static size_t kChunkSize = 1024;
|
|
345
|
-
while (!HasBufferedData() && generate_bytes_length_ > 0)
|
|
346
|
-
{
|
|
347
|
-
size_t len = std::min<size_t>(kChunkSize, generate_bytes_length_);
|
|
348
|
-
std::string data(len, 'a');
|
|
349
|
-
generate_bytes_length_ -= len;
|
|
350
|
-
bool fin = generate_bytes_length_ == 0;
|
|
351
|
-
WriteOrBufferBody(data, fin);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
void Http3ServerStream::SendNotFoundResponse()
|
|
356
|
-
{
|
|
357
|
-
QUIC_DVLOG(1) << "Stream " << id() << " sending not found response.";
|
|
358
|
-
Http2HeaderBlock headers;
|
|
359
|
-
headers[":status"] = "404";
|
|
360
|
-
headers["content-length"] = absl::StrCat(strlen(kNotFoundResponseBody));
|
|
361
|
-
SendHeadersAndBody(std::move(headers), kNotFoundResponseBody);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
void Http3ServerStream::SendErrorResponse()
|
|
365
|
-
{
|
|
366
|
-
SendErrorResponse(0);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
void Http3ServerStream::SendErrorResponse(int resp_code)
|
|
370
|
-
{
|
|
371
|
-
QUIC_DVLOG(1) << "Stream " << id() << " sending error response.";
|
|
372
|
-
if (!reading_stopped())
|
|
373
|
-
{
|
|
374
|
-
StopReading();
|
|
375
|
-
}
|
|
376
|
-
Http2HeaderBlock headers;
|
|
377
|
-
if (resp_code <= 0)
|
|
378
|
-
{
|
|
379
|
-
headers[":status"] = "500";
|
|
380
|
-
}
|
|
381
|
-
else
|
|
382
|
-
{
|
|
383
|
-
headers[":status"] = absl::StrCat(resp_code);
|
|
384
|
-
}
|
|
385
|
-
headers["content-length"] = absl::StrCat(strlen(kErrorResponseBody));
|
|
386
|
-
SendHeadersAndBody(std::move(headers), kErrorResponseBody);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
void Http3ServerStream::SendIncompleteResponse(
|
|
390
|
-
Http2HeaderBlock response_headers,
|
|
391
|
-
absl::string_view body)
|
|
392
|
-
{
|
|
393
|
-
QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = false) : "
|
|
394
|
-
<< response_headers.DebugString();
|
|
395
|
-
WriteHeaders(std::move(response_headers), /*fin=*/false, nullptr);
|
|
396
|
-
QUICHE_DCHECK(!response_sent_);
|
|
397
|
-
response_sent_ = true;
|
|
398
|
-
|
|
399
|
-
QUIC_DLOG(INFO) << "Stream " << id()
|
|
400
|
-
<< " writing body (fin = false) with size: " << body.size();
|
|
401
|
-
if (!body.empty())
|
|
402
|
-
{
|
|
403
|
-
WriteOrBufferBody(body, /*fin=*/false);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
void Http3ServerStream::SendHeadersAndBody(
|
|
408
|
-
Http2HeaderBlock response_headers,
|
|
409
|
-
absl::string_view body)
|
|
410
|
-
{
|
|
411
|
-
SendHeadersAndBodyAndTrailers(std::move(response_headers), body,
|
|
412
|
-
Http2HeaderBlock());
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
void Http3ServerStream::SendHeadersAndBodyAndTrailers(
|
|
416
|
-
Http2HeaderBlock response_headers,
|
|
417
|
-
absl::string_view body,
|
|
418
|
-
Http2HeaderBlock response_trailers)
|
|
419
|
-
{
|
|
420
|
-
// Send the headers, with a FIN if there's nothing else to send.
|
|
421
|
-
bool send_fin = (body.empty() && response_trailers.empty());
|
|
422
|
-
QUIC_DLOG(INFO) << "Stream " << id() << " writing headers (fin = " << send_fin
|
|
423
|
-
<< ") : " << response_headers.DebugString();
|
|
424
|
-
WriteHeaders(std::move(response_headers), send_fin, nullptr);
|
|
425
|
-
QUICHE_DCHECK(!response_sent_);
|
|
426
|
-
response_sent_ = true;
|
|
427
|
-
if (send_fin)
|
|
428
|
-
{
|
|
429
|
-
// Nothing else to send.
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// Send the body, with a FIN if there's no trailers to send.
|
|
434
|
-
send_fin = response_trailers.empty();
|
|
435
|
-
QUIC_DLOG(INFO) << "Stream " << id() << " writing body (fin = " << send_fin
|
|
436
|
-
<< ") with size: " << body.size();
|
|
437
|
-
if (!body.empty() || send_fin)
|
|
438
|
-
{
|
|
439
|
-
WriteOrBufferBody(body, send_fin);
|
|
440
|
-
}
|
|
441
|
-
if (send_fin)
|
|
442
|
-
{
|
|
443
|
-
// Nothing else to send.
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Send the trailers. A FIN is always sent with trailers.
|
|
448
|
-
QUIC_DLOG(INFO) << "Stream " << id() << " writing trailers (fin = true): "
|
|
449
|
-
<< response_trailers.DebugString();
|
|
450
|
-
WriteTrailers(std::move(response_trailers), nullptr);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
void Http3ServerStream::OnInvalidHeaders()
|
|
454
|
-
{
|
|
455
|
-
QUIC_DVLOG(1) << "Invalid headers";
|
|
456
|
-
SendErrorResponse(400);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
const char *const Http3ServerStream::kErrorResponseBody = "bad";
|
|
460
|
-
const char *const Http3ServerStream::kNotFoundResponseBody =
|
|
461
|
-
"file not found";
|
|
462
|
-
|
|
463
|
-
} // namespace quic
|
package/src/http3serverstream.h
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
// modifications
|
|
2
|
-
// Copyright (c) 2022 Marten Richter or other contributers (see commit). All rights reserved.
|
|
3
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
4
|
-
// found in the LICENSE file.
|
|
5
|
-
|
|
6
|
-
// original copyright, see LICENSE.chromium
|
|
7
|
-
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
8
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
9
|
-
// found in the LICENSE file.
|
|
10
|
-
|
|
11
|
-
#ifndef HTTP3_SERVER_STREAM_H
|
|
12
|
-
#define HTTP3_SERVER_STREAM_H
|
|
13
|
-
|
|
14
|
-
#include "absl/strings/string_view.h"
|
|
15
|
-
#include "quiche/quic/core/http/quic_spdy_server_stream_base.h"
|
|
16
|
-
#include "quiche/quic/core/quic_packets.h"
|
|
17
|
-
#include "src/http3serverbackend.h"
|
|
18
|
-
#include "src/http3backendresponse.h"
|
|
19
|
-
#include "quiche/spdy/core/spdy_framer.h"
|
|
20
|
-
|
|
21
|
-
namespace quic
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
// All this does right now is aggregate data, and on fin, send an HTTP
|
|
25
|
-
// response.
|
|
26
|
-
class Http3ServerStream : public QuicSpdyServerStreamBase /*,
|
|
27
|
-
public Http3ServerBackend::RequestHandler*/
|
|
28
|
-
{
|
|
29
|
-
public:
|
|
30
|
-
Http3ServerStream(QuicStreamId id,
|
|
31
|
-
QuicSpdySession *session,
|
|
32
|
-
StreamType type,
|
|
33
|
-
Http3ServerBackend *http3_server_backend);
|
|
34
|
-
Http3ServerStream(PendingStream *pending,
|
|
35
|
-
QuicSpdySession *session,
|
|
36
|
-
Http3ServerBackend *http3_server_backend);
|
|
37
|
-
Http3ServerStream(const Http3ServerStream &) = delete;
|
|
38
|
-
Http3ServerStream &operator=(const Http3ServerStream &) = delete;
|
|
39
|
-
~Http3ServerStream() override;
|
|
40
|
-
|
|
41
|
-
// QuicSpdyStream
|
|
42
|
-
void OnInitialHeadersComplete(bool fin,
|
|
43
|
-
size_t frame_len,
|
|
44
|
-
const QuicHeaderList &header_list) override;
|
|
45
|
-
void OnTrailingHeadersComplete(bool fin,
|
|
46
|
-
size_t frame_len,
|
|
47
|
-
const QuicHeaderList &header_list) override;
|
|
48
|
-
void OnCanWrite() override;
|
|
49
|
-
|
|
50
|
-
// QuicStream implementation called by the sequencer when there is
|
|
51
|
-
// data (or a FIN) to be read.
|
|
52
|
-
void OnBodyAvailable() override;
|
|
53
|
-
|
|
54
|
-
void OnInvalidHeaders() override;
|
|
55
|
-
|
|
56
|
-
// The response body of error responses.
|
|
57
|
-
static const char *const kErrorResponseBody;
|
|
58
|
-
static const char *const kNotFoundResponseBody;
|
|
59
|
-
|
|
60
|
-
// Implements QuicSimpleServerBackend::RequestHandler callbacks
|
|
61
|
-
/* QuicConnectionId connection_id() const override;
|
|
62
|
-
QuicStreamId stream_id() const override;
|
|
63
|
-
std::string peer_host() const override;*/
|
|
64
|
-
void OnResponseBackendComplete(const Http3BackendResponse *response);
|
|
65
|
-
|
|
66
|
-
protected:
|
|
67
|
-
// Sends a basic 200 response using SendHeaders for the headers and WriteData
|
|
68
|
-
// for the body.
|
|
69
|
-
virtual void SendResponse();
|
|
70
|
-
|
|
71
|
-
// Sends a basic 500 response using SendHeaders for the headers and WriteData
|
|
72
|
-
// for the body.
|
|
73
|
-
virtual void SendErrorResponse();
|
|
74
|
-
virtual void SendErrorResponse(int resp_code);
|
|
75
|
-
|
|
76
|
-
// Sends a basic 404 response using SendHeaders for the headers and WriteData
|
|
77
|
-
// for the body.
|
|
78
|
-
void SendNotFoundResponse();
|
|
79
|
-
|
|
80
|
-
// Sends the response header and body, but not the fin.
|
|
81
|
-
void SendIncompleteResponse(spdy::Http2HeaderBlock response_headers,
|
|
82
|
-
absl::string_view body);
|
|
83
|
-
|
|
84
|
-
void SendHeadersAndBody(spdy::Http2HeaderBlock response_headers,
|
|
85
|
-
absl::string_view body);
|
|
86
|
-
void SendHeadersAndBodyAndTrailers(spdy::Http2HeaderBlock response_headers,
|
|
87
|
-
absl::string_view body,
|
|
88
|
-
spdy::Http2HeaderBlock response_trailers);
|
|
89
|
-
|
|
90
|
-
spdy::Http2HeaderBlock *request_headers() { return &request_headers_; }
|
|
91
|
-
|
|
92
|
-
const std::string &body() { return body_; }
|
|
93
|
-
|
|
94
|
-
// Writes the body bytes for the GENERATE_BYTES response type.
|
|
95
|
-
void WriteGeneratedBytes();
|
|
96
|
-
|
|
97
|
-
// The parsed headers received from the client.
|
|
98
|
-
spdy::Http2HeaderBlock request_headers_;
|
|
99
|
-
int64_t content_length_;
|
|
100
|
-
std::string body_;
|
|
101
|
-
// promises not fullfilled from js side or c++ side
|
|
102
|
-
std::set<Http3ServerBackend::WebTransportRespPromisePtr> pending_proms_;
|
|
103
|
-
|
|
104
|
-
private:
|
|
105
|
-
uint64_t generate_bytes_length_;
|
|
106
|
-
// Whether response headers have already been sent.
|
|
107
|
-
bool response_sent_ = false;
|
|
108
|
-
|
|
109
|
-
Http3ServerBackend *http3_server_backend_; // Not owned.
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
} // namespace quic
|
|
113
|
-
|
|
114
|
-
#endif
|
package/src/http3sessioncache.cc
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// modifications
|
|
2
|
-
// Copyright (c) 2022 Marten Richter or other contributers (see commit). All rights reserved.
|
|
3
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
4
|
-
// found in the LICENSE file.
|
|
5
|
-
|
|
6
|
-
// original copyright, see LICENSE.chromium
|
|
7
|
-
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
|
|
8
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
9
|
-
// found in the LICENSE file.
|
|
10
|
-
|
|
11
|
-
#include "src/http3sessioncache.h"
|
|
12
|
-
|
|
13
|
-
#include <memory>
|
|
14
|
-
|
|
15
|
-
#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
|
|
16
|
-
|
|
17
|
-
namespace quic {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
void Http3SessionCache::Insert(const QuicServerId& server_id,
|
|
21
|
-
bssl::UniquePtr<SSL_SESSION> session,
|
|
22
|
-
const TransportParameters& params,
|
|
23
|
-
const ApplicationState* application_state) {
|
|
24
|
-
auto it = cache_entries_.find(server_id);
|
|
25
|
-
if (it == cache_entries_.end()) {
|
|
26
|
-
it = cache_entries_.insert(std::make_pair(server_id, Entry())).first;
|
|
27
|
-
}
|
|
28
|
-
if (session != nullptr) {
|
|
29
|
-
it->second.session = std::move(session);
|
|
30
|
-
}
|
|
31
|
-
if (application_state != nullptr) {
|
|
32
|
-
it->second.application_state =
|
|
33
|
-
std::make_unique<ApplicationState>(*application_state);
|
|
34
|
-
}
|
|
35
|
-
it->second.params = std::make_unique<TransportParameters>(params);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
std::unique_ptr<QuicResumptionState> Http3SessionCache::Lookup(
|
|
39
|
-
const QuicServerId& server_id, QuicWallTime /*now*/,
|
|
40
|
-
const SSL_CTX* /*ctx*/) {
|
|
41
|
-
auto it = cache_entries_.find(server_id);
|
|
42
|
-
if (it == cache_entries_.end()) {
|
|
43
|
-
return nullptr;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!it->second.session) {
|
|
47
|
-
cache_entries_.erase(it);
|
|
48
|
-
return nullptr;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
auto state = std::make_unique<QuicResumptionState>();
|
|
52
|
-
state->tls_session = std::move(it->second.session);
|
|
53
|
-
if (it->second.application_state != nullptr) {
|
|
54
|
-
state->application_state =
|
|
55
|
-
std::make_unique<ApplicationState>(*it->second.application_state);
|
|
56
|
-
}
|
|
57
|
-
state->transport_params =
|
|
58
|
-
std::make_unique<TransportParameters>(*it->second.params);
|
|
59
|
-
state->token = it->second.token;
|
|
60
|
-
return state;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
void Http3SessionCache::ClearEarlyData(const QuicServerId& /*server_id*/) {
|
|
64
|
-
// The simple session cache only stores 1 SSL ticket per entry, so no need to
|
|
65
|
-
// do anything here.
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
void Http3SessionCache::OnNewTokenReceived(const QuicServerId& server_id,
|
|
69
|
-
absl::string_view token) {
|
|
70
|
-
auto it = cache_entries_.find(server_id);
|
|
71
|
-
if (it == cache_entries_.end()) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
it->second.token = std::string(token);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
void Http3SessionCache::RemoveExpiredEntries(QuicWallTime /*now*/) {
|
|
78
|
-
// The simple session cache does not support removing expired entries.
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
void Http3SessionCache::Clear() { cache_entries_.clear(); }
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
} // namespace quic
|
|
85
|
-
|