Provide a WebSocketChannel.
R=kevmoo@google.com
Review URL: https://codereview.chromium.org//1649903002 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee83da1..06c4d4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.1.0
+
+* **Breaking change**: `webSocketHandler()` now passes a
+ [`WebSocketChannel`][WebSocketChannel] to the `onConnection()` callback,
+ rather than a deprecated `CompatibleWebSocket`.
+
+[WebSocketChannel]: https://www.dartdocs.org/documentation/http_parser/2.1.0/http_parser/WebSocketChannel-class.html
+
## 0.0.1+5
* Support `http_parser` 2.0.0.
diff --git a/lib/shelf_web_socket.dart b/lib/shelf_web_socket.dart
index 0866f1f..e233cce 100644
--- a/lib/shelf_web_socket.dart
+++ b/lib/shelf_web_socket.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:http_parser/http_parser.dart';
import 'package:shelf/shelf.dart';
import 'src/web_socket_handler.dart';
@@ -20,8 +21,8 @@
/// This means that this can be placed first in a [Cascade] and only upgrade
/// requests will be handled.
///
-/// The [onConnection] must take a [CompatibleWebSocket] as its first argument.
-/// It may also take a string, the [WebSocket subprotocol][], as its second
+/// The [onConnection] must take a [WebSocketChannel] as its first argument. It
+/// may also take a string, the [WebSocket subprotocol][], as its second
/// argument. The subprotocol is determined by looking at the client's
/// `Sec-WebSocket-Protocol` header and selecting the first entry that also
/// appears in [protocols]. If no subprotocols are shared between the client and
diff --git a/lib/src/web_socket_handler.dart b/lib/src/web_socket_handler.dart
index ea27c61..c0e2c6f 100644
--- a/lib/src/web_socket_handler.dart
+++ b/lib/src/web_socket_handler.dart
@@ -64,8 +64,8 @@
}
var protocol = _chooseProtocol(request);
- request.hijack((stream, byteSink) {
- var sink = UTF8.encoder.startChunkedConversion(byteSink);
+ request.hijack((channel) {
+ var sink = UTF8.encoder.startChunkedConversion(channel.sink);
sink.add(
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
@@ -74,7 +74,7 @@
if (protocol != null) sink.add("Sec-WebSocket-Protocol: $protocol\r\n");
sink.add("\r\n");
- _onConnection(new CompatibleWebSocket(stream, sink: byteSink), protocol);
+ _onConnection(new WebSocketChannel(channel), protocol);
});
// [request.hijack] is guaranteed to throw a [HijackException], so we'll
diff --git a/pubspec.yaml b/pubspec.yaml
index 9395067..46d1c28 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,12 +1,12 @@
name: shelf_web_socket
-version: 0.0.1+5
+version: 0.1.0
author: "Dart Team <misc@dartlang.org>"
homepage: http://github.com/dart-lang/shelf_web_socket
description: >
A WebSocket handler for Shelf.
dependencies:
- http_parser: ">=0.0.2 <3.0.0"
- shelf: ">=0.5.2 <0.7.0"
+ http_parser: "^2.1.0"
+ shelf: ">=0.6.5 <0.8.0"
dev_dependencies:
http: ">=0.10.0 <0.12.0"
test: ">=0.12.0 <0.13.0"
diff --git a/test/web_socket_test.dart b/test/web_socket_test.dart
index 95743d6..b061c04 100644
--- a/test/web_socket_test.dart
+++ b/test/web_socket_test.dart
@@ -17,59 +17,62 @@
};
void main() {
- test("can communicate with a dart:io WebSocket client", () {
- return shelf_io.serve(webSocketHandler((webSocket) {
- webSocket.add("hello!");
- webSocket.first.then((request) {
+ test("can communicate with a dart:io WebSocket client", () async {
+ var server = await shelf_io.serve(webSocketHandler((webSocket) {
+ webSocket.sink.add("hello!");
+ webSocket.stream.first.then((request) {
expect(request, equals("ping"));
- webSocket.add("pong");
- webSocket.close();
+ webSocket.sink.add("pong");
+ webSocket.sink.close();
});
- }), "localhost", 0).then((server) {
- return WebSocket.connect('ws://localhost:${server.port}')
- .then((webSocket) {
- var n = 0;
- return webSocket.listen((message) {
- if (n == 0) {
- expect(message, equals("hello!"));
- webSocket.add("ping");
- } else if (n == 1) {
- expect(message, equals("pong"));
- webSocket.close();
- server.close();
- } else {
- fail("Only expected two messages.");
- }
- n++;
- }).asFuture();
- }).whenComplete(server.close);
- });
+ }), "localhost", 0);
+
+ try {
+ var webSocket = await WebSocket.connect('ws://localhost:${server.port}');
+ var n = 0;
+ await webSocket.listen((message) {
+ if (n == 0) {
+ expect(message, equals("hello!"));
+ webSocket.add("ping");
+ } else if (n == 1) {
+ expect(message, equals("pong"));
+ webSocket.close();
+ server.close();
+ } else {
+ fail("Only expected two messages.");
+ }
+ n++;
+ }).asFuture();
+ } finally {
+ await server.close();
+ }
});
- test("negotiates the sub-protocol", () {
- return shelf_io.serve(webSocketHandler((webSocket, protocol) {
+ test("negotiates the sub-protocol", () async {
+ var server = await shelf_io.serve(webSocketHandler((webSocket, protocol) {
expect(protocol, equals("two"));
- webSocket.close();
- }, protocols: ["three", "two", "x"]), "localhost", 0).then((server) {
- return WebSocket.connect('ws://localhost:${server.port}',
- protocols: ["one", "two", "three"]).then((webSocket) {
- expect(webSocket.protocol, equals("two"));
- return webSocket.close();
- }).whenComplete(server.close);
- });
+ webSocket.sink.close();
+ }, protocols: ["three", "two", "x"]), "localhost", 0);
+
+ try {
+ var webSocket = await WebSocket.connect(
+ 'ws://localhost:${server.port}',
+ protocols: ["one", "two", "three"]);
+ expect(webSocket.protocol, equals("two"));
+ return webSocket.close();
+ } finally {
+ await server.close();
+ }
});
group("with a set of allowed origins", () {
var server;
var url;
- setUp(() {
- return shelf_io.serve(webSocketHandler((webSocket) {
- webSocket.close();
- }, allowedOrigins: ["pub.dartlang.org", "GoOgLe.CoM"]), "localhost", 0)
- .then((server_) {
- server = server_;
- url = 'http://localhost:${server.port}/';
- });
+ setUp(() async {
+ server = await shelf_io.serve(webSocketHandler((webSocket) {
+ webSocket.sink.close();
+ }, allowedOrigins: ["pub.dartlang.org", "GoOgLe.CoM"]), "localhost", 0);
+ url = 'http://localhost:${server.port}/';
});
tearDown(() => server.close());
@@ -104,29 +107,26 @@
});
// Regression test for issue 21894.
- test("allows a Connection header with multiple values", () {
- return shelf_io.serve(webSocketHandler((webSocket) {
- webSocket.close();
- }), "localhost", 0).then((server) {
- var url = 'http://localhost:${server.port}/';
+ test("allows a Connection header with multiple values", () async {
+ var server = await shelf_io.serve(webSocketHandler((webSocket) {
+ webSocket.sink.close();
+ }), "localhost", 0);
- var headers = _handshakeHeaders;
- headers['Connection'] = 'Other-Token, Upgrade';
- expect(http.get(url, headers: headers).whenComplete(server.close),
- hasStatus(101));
- });
+ var url = 'http://localhost:${server.port}/';
+ var headers = _handshakeHeaders;
+ headers['Connection'] = 'Other-Token, Upgrade';
+ expect(http.get(url, headers: headers).whenComplete(server.close),
+ hasStatus(101));
});
group("HTTP errors", () {
var server;
var url;
- setUp(() {
- return shelf_io.serve(webSocketHandler((_) {
+ setUp(() async {
+ server = await shelf_io.serve(webSocketHandler((_) {
fail("should not create a WebSocket");
- }), "localhost", 0).then((server_) {
- server = server_;
- url = 'http://localhost:${server.port}/';
- });
+ }), "localhost", 0);
+ url = 'http://localhost:${server.port}/';
});
tearDown(() => server.close());