Implements `WebSocket` over http/2. This requires a conformant http/2
server supporting the extended connect protocol.
Passes approximately 100 new WPT tests (mostly `?wpt_flags=h2` versions
of existing websockets APIs).
This is implemented as a fallback when http/1.1 fails, so a server that
supports both h1 and h2 WebSockets will still end up on the http/1.1
upgrade path.
The patch also cleas up the websockets handshake to split it up into
http, https+http1 and https+http2, making it a little less intertwined.
This uncovered a likely bug in the WPT test server:
https://github.com/web-platform-tests/wpt/issues/42896
Running `tools/wpt.ts` with a filter would cause an error if there were
extra, leftover expectations in expectations.json. These errors would
not appear if no filter was passed, often leaving the filtered version
of the test runner broken.
This also introduces a smarter bit of logic where filters can be
specified with a leading slash (`tools/wpt.ts run -- /url` is equivalent
to `tools/wpt.ts run -- url`)
This PR ensures that the original signal event is fired before any
dependent signal events.
---
The enabled tests fail on `main`:
```
assert_array_equals: Abort events fired in correct order expected property 0 to be
"original-aborted" but got "clone-aborted" (expected array ["original-aborted", "clone-aborted"]
got ["clone-aborted", "original-aborted"])
```
This PR fixes some crashing WPT tests due to an unresolved promise.
---
This could be a [stream spec](https://streams.spec.whatwg.org) bug
When `controller.close` is called on a byob stream, there's no cleanup
of pending `readIntoRequests`. The only cleanup of pending
`readIntoRequests` happen when `.byobRequest.respond(0)` is called, it
happens
here:6ba245fe25/ext/web/06_streams.js (L2026)
which ends up calling `readIntoRequest.closeSteps(chunk);` in
6ba245fe25/ext/web/06_streams.js (L2070)
To reproduce:
```js
async function byobRead() {
const input = [new Uint8Array([8, 241, 48, 123, 151])];
const stream = new ReadableStream({
type: "bytes",
async pull(controller) {
if(input.length === 0) {
controller.close();
// controller.byobRequest.respond(0); // uncomment for fix
return
}
controller.enqueue(input.shift())
},
});
const reader = stream.getReader({ mode: 'byob' });
const r1 = await reader.read(new Uint8Array(64));
console.log(r1);
const r2 = await reader.read(new Uint8Array(64));
console.log(r2);
}
await byobRead();
```
Running the script triggers:
```
error: Top-level await promise never resolved
```
This addresses issue #19918.
## Issue description
Event messages have the wrong isTrusted value when they are not
triggered by user interaction, which differs from the browser. In
particular, all MessageEvents created by Deno have isTrusted set to
false, even though it should be true.
This is my first ever contribution to Deno, so I might be missing
something.
Fixes the WPT tests that test w/invalid codes. Also explicitly ignoring
some h2 tests to hopefully prevent flakes.
The previous changes to WebSocketStream introduced a bug where the close
errors were not made available if the `pull` method was re-entrant.
Partially supersedes #19016.
This migrates `spawn` and `spawn_blocking` to `deno_core`, and removes
the requirement for `spawn` tasks to be `Send` given our single-threaded
executor.
While we don't need to technically do anything w/`spawn_blocking`, this
allows us to have a single `JoinHandle` type that works for both cases,
and allows us to more easily experiment with alternative
`spawn_blocking` implementations that do not require tokio (ie: rayon).
Async ops (+~35%):
Before:
```
time 1310 ms rate 763358
time 1267 ms rate 789265
time 1259 ms rate 794281
time 1266 ms rate 789889
```
After:
```
time 956 ms rate 1046025
time 954 ms rate 1048218
time 924 ms rate 1082251
time 920 ms rate 1086956
```
HTTP serve (+~4.4%):
Before:
```
Running 10s test @ http://localhost:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 68.78us 19.77us 1.43ms 86.84%
Req/Sec 68.78k 5.00k 73.84k 91.58%
1381833 requests in 10.10s, 167.36MB read
Requests/sec: 136823.29
Transfer/sec: 16.57MB
```
After:
```
Running 10s test @ http://localhost:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 63.12us 17.43us 1.11ms 85.13%
Req/Sec 71.82k 3.71k 77.02k 79.21%
1443195 requests in 10.10s, 174.79MB read
Requests/sec: 142921.99
Transfer/sec: 17.31MB
```
Suggested-By: alice@ryhl.io
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This reverts commit 4c2269d64a.
> This update introduced more flakiness to the tests on CI, we are going
> to investigate and reland this update after Deno 1.32.0 is released.
This reverts commit 29fb7709ed.
This update introduced more flakiness to the tests on CI, we are going
to investigate and reland this update after Deno 1.32.0 is released.
- relands #17872
- updates the timeouts to be re-configurable just for CI
- fixes `./tools/wpt.ts update`
- adds option not "ignore" during, applied to wpt epoch runs only
Previously the inner request object of the original and the new request
were the same, causing the requests to be entangled and mutable changes
to one to be visible to the other. This fixes that.
https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
> If httpRequest’s header list contains `Range`, then append
(`Accept-Encoding`, `identity`)
> to httpRequest’s header list.
>
> This avoids a failure when handling content codings with a part of an
encoded response.
> Additionally, many servers mistakenly ignore `Range` headers if a
non-identity encoding is accepted.