forked from mirrors/gecko-dev
Bug 1881996 [wpt PR 44779] - WebSocketStream: Use one WebSocketError object to error everything, a=testonly
Automatic update from web-platform-tests WebSocketStream: Use one WebSocketError object to error everything Error readable, writable and wss.closed with the same WebSocketError object. Also add wpts for this and other close error scenarios. Bug: 41470216 Change-Id: I0c68390ba4e7bef9db6a19516ac4afc77ed290e2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5321157 Reviewed-by: Nidhi Jaju <nidhijaju@chromium.org> Commit-Queue: Adam Rice <ricea@chromium.org> Cr-Commit-Position: refs/heads/main@{#1266302} -- wpt-commits: b60fb68111b38161c17108433d6650bfb7ed1e5b wpt-pr: 44779
This commit is contained in:
parent
7225381216
commit
2de9501a20
4 changed files with 152 additions and 0 deletions
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright (c) 2024 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""
|
||||
Wait for a Close frame from the client and then close the connection without
|
||||
sending a Close frame in return.
|
||||
"""
|
||||
|
||||
from mod_pywebsocket.handshake import AbortedByUserException
|
||||
|
||||
|
||||
def web_socket_do_extra_handshake(request):
|
||||
pass
|
||||
|
||||
|
||||
def web_socket_transfer_data(request):
|
||||
while True:
|
||||
if request.ws_stream.receive_message() is None:
|
||||
return
|
||||
|
||||
|
||||
def web_socket_passive_closing_handshake(request):
|
||||
raise AbortedByUserException('abrupt close')
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright (c) 2024 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""
|
||||
Perform a server-initiated close according to the parameters passed in the
|
||||
query string. Supported parameters:
|
||||
|
||||
* code=INT: The close code to send in the close frame. If omitted the Close
|
||||
frame will have an empty body.
|
||||
|
||||
* reason=TEXT: The reason to be sent in the close frame. Only sent if `code` is
|
||||
set.
|
||||
|
||||
* abrupt=1: Close the connection without sending a Close frame.
|
||||
|
||||
Example: /remote-close?code=1000&reason=Done
|
||||
|
||||
"""
|
||||
|
||||
import urllib
|
||||
|
||||
from mod_pywebsocket.handshake import AbortedByUserException
|
||||
|
||||
|
||||
def web_socket_do_extra_handshake(request):
|
||||
pass
|
||||
|
||||
|
||||
def web_socket_transfer_data(request):
|
||||
parts = urllib.parse.urlsplit(request.uri)
|
||||
parameters = urllib.parse.parse_qs(parts.query)
|
||||
if 'abrupt' in parameters:
|
||||
# Send a ping frame to make sure this isn't misinterpreted as a
|
||||
# handshake failure.
|
||||
request.ws_stream.send_ping('ping')
|
||||
# Rudely close the connection.
|
||||
raise AbortedByUserException('Abort the connection')
|
||||
code = None
|
||||
reason = None
|
||||
if 'code' in parameters:
|
||||
code = int(parameters['code'][0])
|
||||
reason = parameters.get('reason', [''])[0]
|
||||
request.ws_stream.close_connection(code, reason)
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// META: script=../../constants.sub.js
|
||||
// META: script=resources/url-constants.js
|
||||
// META: global=window,worker
|
||||
// META: variant=?default
|
||||
// META: variant=?wss
|
||||
// META: variant=?wpt_flags=h2
|
||||
|
||||
|
|
@ -108,6 +109,15 @@ promise_test(async () => {
|
|||
'one second should have elapsed');
|
||||
}, 'writer close() promise should not resolve until handshake completes');
|
||||
|
||||
promise_test(async t => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/passive-close-abort`);
|
||||
await wss.opened;
|
||||
wss.close({closeCode: 4000, reason: 'because'});
|
||||
const error = await wss.closed.then(t.unreached_func('closed should reject'), e => e);
|
||||
assert_equals(error.constructor, WebSocketError, 'error should be WebSocketError');
|
||||
assert_equals(error.closeCode, 1006, 'close code should be Abnormal Closure');
|
||||
}, 'incomplete closing handshake should be considered unclean close');
|
||||
|
||||
const abortOrCancel = [
|
||||
{
|
||||
method: 'abort',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
// META: script=../../constants.sub.js
|
||||
// META: script=resources/url-constants.js
|
||||
// META: global=window,worker
|
||||
// META: variant=?default
|
||||
// META: variant=?wss
|
||||
// META: variant=?wpt_flags=h2
|
||||
|
||||
'use strict';
|
||||
|
||||
promise_test(async t => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/remote-close?code=1000`);
|
||||
const { readable, writable } = await wss.opened;
|
||||
const { closeCode, reason } = await wss.closed;
|
||||
assert_equals(closeCode, 1000, 'code should be 1000');
|
||||
assert_equals(reason, '', 'reason should be empty');
|
||||
const { value, done } = await readable.getReader().read();
|
||||
assert_true(done, 'readable should be closed');
|
||||
await promise_rejects_dom(t, 'InvalidStateError', writable.getWriter().ready,
|
||||
'writable should be errored');
|
||||
}, 'clean close should be clean');
|
||||
|
||||
promise_test(async () => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/remote-close`);
|
||||
const { closeCode, reason } = await wss.closed;
|
||||
assert_equals(closeCode, 1005, 'code should be No Status Rcvd');
|
||||
assert_equals(reason, '', 'reason should be empty');
|
||||
}, 'close frame with no body should result in status code 1005');
|
||||
|
||||
promise_test(async () => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/remote-close?code=4000&reason=robot`);
|
||||
const { closeCode, reason } = await wss.closed;
|
||||
assert_equals(closeCode, 4000, 'code should be 4000');
|
||||
assert_equals(reason, 'robot', 'reason should be set');
|
||||
}, 'reason should be passed through');
|
||||
|
||||
promise_test(async () => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/remote-close?code=4000&` +
|
||||
'reason=%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88');
|
||||
const { reason } = await wss.closed;
|
||||
assert_equals(reason, 'ロボット', 'reason should be set');
|
||||
}, 'UTF-8 reason should work');
|
||||
|
||||
promise_test(async t => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/remote-close?code=4567`);
|
||||
const { writable } = await wss.opened;
|
||||
const veryLargeMessage = new Uint8Array(20 * 1024 * 1024); // 20MB.
|
||||
const writePromise = writable.getWriter().write(veryLargeMessage);
|
||||
const closedError = await wss.closed.then(t.unreached_func('closed should reject'), e => e);
|
||||
assert_equals(closedError.constructor, WebSocketError, 'error should be WebSocketError');
|
||||
assert_equals(closedError.closeCode, 4567, 'closeCode should be set');
|
||||
promise_rejects_js(t, WebSocketError, writePromise, 'write() should reject');
|
||||
}, 'close with unwritten data should not be considered clean');
|
||||
|
||||
promise_test(async t => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/remote-close?code=4222&reason=remote`);
|
||||
await wss.opened;
|
||||
wss.close({closeCode: 4111, reason: 'local'});
|
||||
const { closeCode, reason } = await wss.closed;
|
||||
assert_equals(closeCode, 4222, 'remote code should be used');
|
||||
assert_equals(reason, 'remote', 'remote reason should be used');
|
||||
}, 'remote code and reason should be used');
|
||||
|
||||
promise_test(async t => {
|
||||
const wss = new WebSocketStream(`${BASEURL}/remote-close?abrupt=1`);
|
||||
const { readable, writable } = await wss.opened;
|
||||
const closedError = await wss.closed.then(t.unreached_func('closed should reject'), e => e);
|
||||
assert_equals(closedError.constructor, WebSocketError, 'error should be a WebSocketError');
|
||||
assert_equals(closedError.name, 'WebSocketError', 'error name should be WebSocketError');
|
||||
assert_equals(closedError.closeCode, 1006, 'code should be Abnormal Closure');
|
||||
await promise_rejects_exactly(t, closedError, readable.getReader().read(),
|
||||
'readable should be errored with the same object');
|
||||
await promise_rejects_exactly(t, closedError, writable.getWriter().ready,
|
||||
'writable should be errored with the same object');
|
||||
}, 'abrupt close should give an error');
|
||||
Loading…
Reference in a new issue