Skip to content

Commit

Permalink
Add CONNECT response WPTs for WebTransport
Browse files Browse the repository at this point in the history
This CL adds 7 test cases:
- establish WebTransport connection with different status codes
- echo the CONNECT request headers
- setting a cookie in a CONNECT request, and then making sure the
"cookie" header is not echoed back

The echo-request-headers server handler is also added in this CL, which
sends the CONNECT request headers over a unidirectional stream.

Bug: 1201569
Change-Id: I30d8092af42dc2505cadbc15bf0573f8815758bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3134980
Commit-Queue: Nidhi Jaju <nidhijaju@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: Adam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/heads/main@{#918651}
  • Loading branch information
nidhijaju authored and chromium-wpt-export-bot committed Sep 7, 2021
1 parent 8a2b0f1 commit 23fa10b
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
73 changes: 73 additions & 0 deletions webtransport/connect.sub.any.js
@@ -0,0 +1,73 @@
// META: global=window,worker
// META: script=/common/get-host-info.sub.js
// META: script=resources/webtransport-test-helpers.sub.js

promise_test(async t => {
const wt = new WebTransport(webtransport_url('custom-response.py?:status=200'));
await wt.ready;
}, 'WebTransport connection succeeds with status code 200');

promise_test(async t => {
const wt = new WebTransport(webtransport_url('custom-response.py?:status=204'));
await wt.ready;
}, 'WebTransport connection succeeds with status code 204');

promise_test(async t => {
const wt = new WebTransport(webtransport_url('custom-response.py?:status=301'));
await promise_rejects_js(t, TypeError, wt.ready, 'ready promise shoud be rejected');
await promise_rejects_js(t, TypeError, wt.closed, 'closed promise should be rejected');
}, 'WebTransport connection fails with status code 301');

promise_test(async t => {
const wt = new WebTransport(webtransport_url('custom-response.py?:status=401'));
await promise_rejects_js(t, TypeError, wt.ready, 'ready promise should be rejected');
await promise_rejects_js(t, TypeError, wt.closed, 'closed promise should be rejected');
}, 'WebTransport connection fails with status code 401');

promise_test(async t => {
const wt = new WebTransport(webtransport_url('custom-response.py?:status=404'));
await promise_rejects_js(t, TypeError, wt.ready, 'ready promise should be rejected');
await promise_rejects_js(t, TypeError, wt.closed, 'closed promise should be rejected');
}, 'WebTransport connection fails with status code 404');

promise_test(async t => {
// Create WebTransport session.
const wt = new WebTransport(webtransport_url('echo-request-headers.py'));
await wt.ready;

// Read incoming unidirectional stream for echoed request headers.
const streams = await wt.incomingUnidirectionalStreams;

const stream_reader = streams.getReader();
const { value: recv_stream } = await stream_reader.read();
stream_reader.releaseLock();

const request_headers = await read_stream_as_json(recv_stream);

// Check the standard request headers.
check_and_remove_standard_headers(request_headers);
}, 'Echo back request headers');

promise_test(async t => {
// Create WebTransport session, and attach "Set-Cookie: foo=bar" to the response of
// the handshake.
const encodedSetCookie = encodeURIComponent('foo=bar');
let wt = new WebTransport(webtransport_url('custom-response.py?set-cookie=' + encodedSetCookie));
await wt.ready;

wt = new WebTransport(webtransport_url('echo-request-headers.py'));
await wt.ready;

// Read incoming unidirectional stream for echoed request headers.
const streams = await wt.incomingUnidirectionalStreams;

const stream_reader = streams.getReader();
const { value: recv_stream } = await stream_reader.read();
stream_reader.releaseLock();

const request_headers = await read_stream_as_json(recv_stream);

// Check cookie header is not echoed back.
check_and_remove_standard_headers(request_headers);
assert_equals(request_headers['cookie'], undefined);
}, 'Cookie header is not echoed back');
11 changes: 11 additions & 0 deletions webtransport/handlers/echo-request-headers.py
@@ -0,0 +1,11 @@
import json


def session_established(session):
headers = {}
for name, value in session.request_headers:
headers[name.decode('utf-8')] = value.decode('utf-8')

stream_id = session.create_unidirectional_stream()
data = json.dumps(headers).encode('utf-8')
session.send_stream_data(stream_id, data, end_stream=True)
49 changes: 49 additions & 0 deletions webtransport/resources/webtransport-test-helpers.sub.js
@@ -0,0 +1,49 @@
// The file including this must also include /common/get-host-info.sub.js to
// pick up the necessary constants.

const HOST = get_host_info().ORIGINAL_HOST;
const PORT = '{{ports[webtransport-h3][0]}}';
const BASE = `https://${HOST}:${PORT}`;

// Create URL for WebTransport session.
function webtransport_url(handler) {
return `${BASE}/webtransport/handlers/${handler}`;
}

// Decode all chunks in a given ReadableStream.
async function read_stream_as_json(stream) {
const decoder = new TextDecoderStream('utf-8');
const decode_stream = stream.readable.pipeThrough(decoder);
const reader = decode_stream.getReader();

let chunks = '';
while (true) {
const {value: chunk, done} = await reader.read();
if (done) {
break;
}
chunks += chunk;
}
reader.releaseLock();

return JSON.parse(chunks);
}

// Check the standard request headers and delete them, leaving any "unique"
// headers to check in the test.
function check_and_remove_standard_headers(headers) {
assert_equals(headers[':scheme'], 'https');
delete headers[':scheme'];
assert_equals(headers[':method'], 'CONNECT');
delete headers[':method'];
assert_equals(headers[':authority'], `${HOST}:${PORT}`);
delete headers[':authority'];
assert_equals(headers[':path'], '/webtransport/handlers/echo-request-headers.py');
delete headers[':path'];
assert_equals(headers[':protocol'], 'webtransport');
delete headers[':protocol'];
assert_equals(headers['origin'], `${get_host_info().ORIGIN}`);
delete headers['origin'];
assert_equals(headers['datagram-flow-id'], '0');
delete headers['datagram-flow-id'];
}

0 comments on commit 23fa10b

Please sign in to comment.