Skip to content

Commit

Permalink
Allow 1000 as a WebSocket close code (#1211)
Browse files Browse the repository at this point in the history
Fixes #1203
  • Loading branch information
brianquinlan committed May 24, 2024
1 parent f361779 commit 0937562
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 10 deletions.
4 changes: 4 additions & 0 deletions pkgs/cupertino_http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.5.1-wip

* Allow `1000` as a `code` argument in `CupertinoWebSocket.close`.

## 1.5.0

* Add integration to the
Expand Down
5 changes: 3 additions & 2 deletions pkgs/cupertino_http/lib/src/cupertino_web_socket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,9 @@ class CupertinoWebSocket implements WebSocket {
throw WebSocketConnectionClosed();
}

if (code != null) {
RangeError.checkValueInInterval(code, 3000, 4999, 'code');
if (code != null && code != 1000 && !(code >= 3000 && code <= 4999)) {
throw ArgumentError('Invalid argument: $code, close code must be 1000 or '
'in the range 3000-4999');
}
if (reason != null && utf8.encode(reason).length > 123) {
throw ArgumentError.value(reason, 'reason',
Expand Down
2 changes: 1 addition & 1 deletion pkgs/cupertino_http/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cupertino_http
version: 1.5.0
version: 1.5.1-wip
description: >-
A macOS/iOS Flutter plugin that provides access to the Foundation URL
Loading System.
Expand Down
4 changes: 4 additions & 0 deletions pkgs/web_socket/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.1.5

- Allow `1000` as a close code.

## 0.1.4

- Add a `fakes` function that returns a pair of `WebSocket`s useful in
Expand Down
5 changes: 3 additions & 2 deletions pkgs/web_socket/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import 'dart:convert';

/// Throw if the given close code is not valid.
void checkCloseCode(int? code) {
if (code != null) {
RangeError.checkValueInInterval(code, 3000, 4999, 'code');
if (code != null && code != 1000 && !(code >= 3000 && code <= 4999)) {
throw ArgumentError('Invalid argument: $code, close code must be 1000 or '
'in the range 3000-4999');
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkgs/web_socket/lib/src/web_socket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ abstract interface class WebSocket {
/// [code] is set then the peer will see a 1005 status code. If no [reason]
/// is set then the peer will not receive a reason string.
///
/// Throws a [RangeError] if [code] is not in the range 3000-4999.
/// Throws an [ArgumentError] if [code] is not 1000 or in the range 3000-4999.
///
/// Throws an [ArgumentError] if [reason] is longer than 123 bytes when
/// encoded as UTF-8
Expand Down
2 changes: 1 addition & 1 deletion pkgs/web_socket/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: >-
Any easy-to-use library for communicating with WebSockets
that has multiple implementations.
repository: https://github.com/dart-lang/http/tree/master/pkgs/web_socket
version: 0.1.4
version: 0.1.5

environment:
sdk: ^3.3.0
Expand Down
2 changes: 1 addition & 1 deletion pkgs/web_socket/test/fake_web_socket_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void proxy(WebSocket from, WebSocket to) {
case BinaryDataReceived(:final data):
to.sendBytes(data);
case CloseReceived(:var code, :final reason):
if (code != null && (code < 3000 || code > 4999)) {
if (code != null && code != 1000 && (code < 3000 || code > 4999)) {
code = null;
}
to.close(code, reason);
Expand Down
29 changes: 27 additions & 2 deletions pkgs/web_socket_conformance_tests/lib/src/close_local_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,22 @@ void testCloseLocal(
httpServerChannel.sink.add(null);
});

test('reserved close code', () async {
test('reserved close code: 1004', () async {
final channel = await channelFactory(uri);
await expectLater(() => channel.close(1004), throwsA(isA<RangeError>()));
await expectLater(
() => channel.close(1004), throwsA(isA<ArgumentError>()));
});

test('reserved close code: 2999', () async {
final channel = await channelFactory(uri);
await expectLater(
() => channel.close(2999), throwsA(isA<ArgumentError>()));
});

test('reserved close code: 5000', () async {
final channel = await channelFactory(uri);
await expectLater(
() => channel.close(5000), throwsA(isA<ArgumentError>()));
});

test('too long close reason', () async {
Expand All @@ -78,6 +91,18 @@ void testCloseLocal(
expect(await channel.events.isEmpty, true);
});

test('close with 1000', () async {
final channel = await channelFactory(uri);

await channel.close(1000);
final closeCode = await httpServerQueue.next as int?;
final closeReason = await httpServerQueue.next as String?;

expect(closeCode, 1000);
expect(closeReason, '');
expect(await channel.events.isEmpty, true);
});

test('with code 3000', () async {
final channel = await channelFactory(uri);

Expand Down

0 comments on commit 0937562

Please sign in to comment.