Skip to content

Commit

Permalink
Remove support for requests not made through dart:io Sockets (#423)
Browse files Browse the repository at this point in the history
  • Loading branch information
brianquinlan authored Apr 5, 2024
1 parent 68cb864 commit 7352d1b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
4 changes: 3 additions & 1 deletion pkgs/shelf_web_socket/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## 1.0.5-wip
## 2.0.0-wip

* Require Dart `^3.0.0`.
* **BREAKING:**: Remove support for hijacking WebSocket requests that are not
being transported using `dart:io` `Socket`s.

## 1.0.4

Expand Down
13 changes: 11 additions & 2 deletions pkgs/shelf_web_socket/lib/src/web_socket_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:shelf/shelf.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

/// A class that exposes a handler for upgrading WebSocket requests.
Expand Down Expand Up @@ -78,9 +80,16 @@ class WebSocketHandler {
if (protocol != null) sink.add('Sec-WebSocket-Protocol: $protocol\r\n');
sink.add('\r\n');

if (channel.sink is! Socket) {
throw ArgumentError('channel.sink must be a dart:io `Socket`.');
}

final webSocket = WebSocket.fromUpgradedSocket(channel.sink as Socket,
protocol: protocol, serverSide: true)
..pingInterval = _pingInterval;

// ignore: avoid_dynamic_calls
_onConnection(
WebSocketChannel(channel, pingInterval: _pingInterval), protocol);
_onConnection(IOWebSocketChannel(webSocket), protocol);
});
}

Expand Down
7 changes: 6 additions & 1 deletion pkgs/shelf_web_socket/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: shelf_web_socket
version: 1.0.5-wip
version: 2.0.0-wip
description: >
A shelf handler that wires up a listener for every connection.
repository: https://github.com/dart-lang/shelf/tree/master/pkgs/shelf_web_socket
Expand All @@ -20,3 +20,8 @@ dev_dependencies:
dart_flutter_team_lints: ^2.0.0
http: '>=0.13.0 <2.0.0'
test: ^1.16.0

# Remove this when a version of `package:test` is released that is compatible
# with self_web_socket 2.x
dependency_overrides:
test: 1.25.2
28 changes: 28 additions & 0 deletions pkgs/shelf_web_socket/test/web_socket_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_web_socket/shelf_web_socket.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test/test.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

Expand Down Expand Up @@ -103,6 +105,32 @@ void main() {
}
});

test('cannot hijack non-Socket StreamChannel', () async {
final handler =
webSocketHandler((WebSocketChannel webSocket, String? protocol) {
expect(protocol, isNull);
webSocket.sink.close();
});

expect(
() => handler(Request('GET', Uri.parse('ws://example.com/'),
protocolVersion: '1.1',
headers: {
'Host': 'example.com',
'Upgrade': 'websocket',
'Connection': 'Upgrade',
'Sec-WebSocket-Key': 'x3JJHMbDL1EzLkh9GBhXDw==',
'Sec-WebSocket-Version': '13',
'Origin': 'http://example.com',
}, onHijack: (fn) {
// `.foreign` is not a Socket so hijacking the request should
// fail.
expect(() => fn(StreamChannelController<List<int>>().foreign),
throwsArgumentError);
})),
throwsA(isA<HijackException>()));
});

group('with a set of allowed origins', () {
late HttpServer server;
late Uri url;
Expand Down

0 comments on commit 7352d1b

Please sign in to comment.