diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000..73833e578a14b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: dart + +dart: + - dev + - stable + +dart_task: + - test + +matrix: + include: + # Only validate formatting using the dev release + - dart: dev + dart_task: dartfmt + - dart: dev + dart_task: analyzer + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache diff --git a/lib/shelf_web_socket.dart b/lib/shelf_web_socket.dart index 3d376aafb2ef9..9c9239d14b6f9 100644 --- a/lib/shelf_web_socket.dart +++ b/lib/shelf_web_socket.dart @@ -38,12 +38,12 @@ typedef _BinaryFunction(arg1, arg2); /// See also the WebSocket spec's discussion of [origin considerations][]. /// /// [origin considerations]: https://tools.ietf.org/html/rfc6455#section-10.2 -Handler webSocketHandler(Function onConnection, {Iterable protocols, - Iterable allowedOrigins}) { +Handler webSocketHandler(Function onConnection, + {Iterable protocols, Iterable allowedOrigins}) { if (protocols != null) protocols = protocols.toSet(); if (allowedOrigins != null) { - allowedOrigins = allowedOrigins - .map((origin) => origin.toLowerCase()).toSet(); + allowedOrigins = + allowedOrigins.map((origin) => origin.toLowerCase()).toSet(); } if (onConnection is! _BinaryFunction) { diff --git a/lib/src/web_socket_handler.dart b/lib/src/web_socket_handler.dart index b8f94a239a591..05b7bb4022113 100644 --- a/lib/src/web_socket_handler.dart +++ b/lib/src/web_socket_handler.dart @@ -26,8 +26,8 @@ class WebSocketHandler { var connection = request.headers['Connection']; if (connection == null) return _notFound(); - var tokens = connection.toLowerCase().split(',') - .map((token) => token.trim()); + var tokens = + connection.toLowerCase().split(',').map((token) => token.trim()); if (!tokens.contains('upgrade')) return _notFound(); var upgrade = request.headers['Upgrade']; @@ -58,7 +58,8 @@ class WebSocketHandler { // unexpected origins, we ensure that malicious JavaScript is unable to fake // a WebSocket handshake. var origin = request.headers['Origin']; - if (origin != null && _allowedOrigins != null && + if (origin != null && + _allowedOrigins != null && !_allowedOrigins.contains(origin.toLowerCase())) { return _forbidden('invalid origin "$origin".'); } @@ -66,8 +67,7 @@ class WebSocketHandler { var protocol = _chooseProtocol(request); request.hijack((channel) { var sink = UTF8.encoder.startChunkedConversion(channel.sink); - sink.add( - "HTTP/1.1 101 Switching Protocols\r\n" + sink.add("HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: ${WebSocketChannel.signKey(key)}\r\n"); @@ -97,20 +97,20 @@ class WebSocketHandler { } /// Returns a 404 Not Found response. - Response _notFound() => _htmlResponse(404, "404 Not Found", - "Only WebSocket connections are supported."); + Response _notFound() => _htmlResponse( + 404, "404 Not Found", "Only WebSocket connections are supported."); /// Returns a 400 Bad Request response. /// /// [message] will be HTML-escaped before being included in the response body. - Response _badRequest(String message) => _htmlResponse(400, "400 Bad Request", - "Invalid WebSocket upgrade request: $message"); + Response _badRequest(String message) => _htmlResponse( + 400, "400 Bad Request", "Invalid WebSocket upgrade request: $message"); /// Returns a 403 Forbidden response. /// /// [message] will be HTML-escaped before being included in the response body. - Response _forbidden(String message) => _htmlResponse(403, "403 Forbidden", - "WebSocket upgrade refused: $message"); + Response _forbidden(String message) => _htmlResponse( + 403, "403 Forbidden", "WebSocket upgrade refused: $message"); /// Creates an HTTP response with the given [statusCode] and an HTML body with /// [title] and [message]. diff --git a/test/web_socket_test.dart b/test/web_socket_test.dart index b061c04f57e83..6b83d945142e0 100644 --- a/test/web_socket_test.dart +++ b/test/web_socket_test.dart @@ -10,11 +10,11 @@ import 'package:shelf_web_socket/shelf_web_socket.dart'; import 'package:test/test.dart'; Map get _handshakeHeaders => { - "Upgrade": "websocket", - "Connection": "Upgrade", - "Sec-WebSocket-Key": "x3JJHMbDL1EzLkh9GBhXDw==", - "Sec-WebSocket-Version": "13" -}; + "Upgrade": "websocket", + "Connection": "Upgrade", + "Sec-WebSocket-Key": "x3JJHMbDL1EzLkh9GBhXDw==", + "Sec-WebSocket-Version": "13" + }; void main() { test("can communicate with a dart:io WebSocket client", () async { @@ -49,14 +49,16 @@ void main() { }); test("negotiates the sub-protocol", () async { - var server = await shelf_io.serve(webSocketHandler((webSocket, protocol) { - expect(protocol, equals("two")); - webSocket.sink.close(); - }, protocols: ["three", "two", "x"]), "localhost", 0); + var server = await shelf_io.serve( + webSocketHandler((webSocket, protocol) { + expect(protocol, equals("two")); + webSocket.sink.close(); + }, protocols: ["three", "two", "x"]), + "localhost", + 0); try { - var webSocket = await WebSocket.connect( - 'ws://localhost:${server.port}', + var webSocket = await WebSocket.connect('ws://localhost:${server.port}', protocols: ["one", "two", "three"]); expect(webSocket.protocol, equals("two")); return webSocket.close(); @@ -69,9 +71,12 @@ void main() { var server; var url; setUp(() async { - server = await shelf_io.serve(webSocketHandler((webSocket) { - webSocket.sink.close(); - }, allowedOrigins: ["pub.dartlang.org", "GoOgLe.CoM"]), "localhost", 0); + server = await shelf_io.serve( + webSocketHandler((webSocket) { + webSocket.sink.close(); + }, allowedOrigins: ["pub.dartlang.org", "GoOgLe.CoM"]), + "localhost", + 0); url = 'http://localhost:${server.port}/'; }); @@ -173,7 +178,7 @@ void main() { } Matcher hasStatus(int status) => completion(predicate((response) { - expect(response, new isInstanceOf()); - expect(response.statusCode, equals(status)); - return true; -})); + expect(response, new isInstanceOf()); + expect(response.statusCode, equals(status)); + return true; + }));