Skip to content

Commit 7352d1b

Browse files
authored
Remove support for requests not made through dart:io Sockets (#423)
1 parent 68cb864 commit 7352d1b

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

pkgs/shelf_web_socket/CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
## 1.0.5-wip
1+
## 2.0.0-wip
22

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

57
## 1.0.4
68

pkgs/shelf_web_socket/lib/src/web_socket_handler.dart

+11-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:convert';
6+
import 'dart:io';
67

78
import 'package:shelf/shelf.dart';
9+
import 'package:web_socket_channel/io.dart';
810
import 'package:web_socket_channel/web_socket_channel.dart';
911

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

83+
if (channel.sink is! Socket) {
84+
throw ArgumentError('channel.sink must be a dart:io `Socket`.');
85+
}
86+
87+
final webSocket = WebSocket.fromUpgradedSocket(channel.sink as Socket,
88+
protocol: protocol, serverSide: true)
89+
..pingInterval = _pingInterval;
90+
8191
// ignore: avoid_dynamic_calls
82-
_onConnection(
83-
WebSocketChannel(channel, pingInterval: _pingInterval), protocol);
92+
_onConnection(IOWebSocketChannel(webSocket), protocol);
8493
});
8594
}
8695

pkgs/shelf_web_socket/pubspec.yaml

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: shelf_web_socket
2-
version: 1.0.5-wip
2+
version: 2.0.0-wip
33
description: >
44
A shelf handler that wires up a listener for every connection.
55
repository: https://github.com/dart-lang/shelf/tree/master/pkgs/shelf_web_socket
@@ -20,3 +20,8 @@ dev_dependencies:
2020
dart_flutter_team_lints: ^2.0.0
2121
http: '>=0.13.0 <2.0.0'
2222
test: ^1.16.0
23+
24+
# Remove this when a version of `package:test` is released that is compatible
25+
# with self_web_socket 2.x
26+
dependency_overrides:
27+
test: 1.25.2

pkgs/shelf_web_socket/test/web_socket_test.dart

+28
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import 'dart:io';
66

77
import 'package:http/http.dart' as http;
8+
import 'package:shelf/shelf.dart';
89
import 'package:shelf/shelf_io.dart' as shelf_io;
910
import 'package:shelf_web_socket/shelf_web_socket.dart';
11+
import 'package:stream_channel/stream_channel.dart';
1012
import 'package:test/test.dart';
1113
import 'package:web_socket_channel/web_socket_channel.dart';
1214

@@ -103,6 +105,32 @@ void main() {
103105
}
104106
});
105107

108+
test('cannot hijack non-Socket StreamChannel', () async {
109+
final handler =
110+
webSocketHandler((WebSocketChannel webSocket, String? protocol) {
111+
expect(protocol, isNull);
112+
webSocket.sink.close();
113+
});
114+
115+
expect(
116+
() => handler(Request('GET', Uri.parse('ws://example.com/'),
117+
protocolVersion: '1.1',
118+
headers: {
119+
'Host': 'example.com',
120+
'Upgrade': 'websocket',
121+
'Connection': 'Upgrade',
122+
'Sec-WebSocket-Key': 'x3JJHMbDL1EzLkh9GBhXDw==',
123+
'Sec-WebSocket-Version': '13',
124+
'Origin': 'http://example.com',
125+
}, onHijack: (fn) {
126+
// `.foreign` is not a Socket so hijacking the request should
127+
// fail.
128+
expect(() => fn(StreamChannelController<List<int>>().foreign),
129+
throwsArgumentError);
130+
})),
131+
throwsA(isA<HijackException>()));
132+
});
133+
106134
group('with a set of allowed origins', () {
107135
late HttpServer server;
108136
late Uri url;

0 commit comments

Comments
 (0)