OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 // | |
5 // VMOptions= | |
6 // VMOptions=--short_socket_read | |
7 // VMOptions=--short_socket_write | |
8 // VMOptions=--short_socket_read --short_socket_write | |
9 | |
10 import "dart:async"; | |
11 import "dart:convert"; | |
12 import "dart:io"; | |
13 import "dart:typed_data"; | |
14 | |
15 import "package:async_helper/async_helper.dart"; | |
16 import "package:crypto/crypto.dart"; | |
17 import "package:expect/expect.dart"; | |
18 import "package:path/path.dart"; | |
19 | |
20 const WEB_SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | |
21 | |
22 const String HOST_NAME = 'localhost'; | |
23 | |
24 class SecurityConfiguration { | |
25 final bool secure; | |
26 | |
27 SecurityConfiguration({bool this.secure}); | |
28 | |
29 Future<HttpServer> createServer({int backlog: 0}) => | |
30 secure ? HttpServer.bindSecure(HOST_NAME, | |
31 0, | |
32 serverContext, | |
33 backlog: backlog) | |
34 : HttpServer.bind(HOST_NAME, | |
35 0, | |
36 backlog: backlog); | |
37 | |
38 Future<WebSocket> createClient(int port) => | |
39 // TODO(whesse): Add client context argument to WebSocket.connect | |
40 WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/'); | |
41 | |
42 void testCompressionSupport({server: false, | |
43 client: false, | |
44 contextTakeover: false}) { | |
45 asyncStart(); | |
46 | |
47 var clientOptions = new CompressionOptions( | |
48 enabled: client, | |
49 serverNoContextTakeover: contextTakeover, | |
50 clientNoContextTakeover: contextTakeover); | |
51 var serverOptions = new CompressionOptions( | |
52 enabled: server, | |
53 serverNoContextTakeover: contextTakeover, | |
54 clientNoContextTakeover: contextTakeover); | |
55 | |
56 createServer().then((server) { | |
57 server.listen((request) { | |
58 Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request)); | |
59 WebSocketTransformer.upgrade(request, compression: serverOptions) | |
60 .then((webSocket) { | |
61 webSocket.listen((message) { | |
62 Expect.equals("Hello World", message); | |
63 | |
64 webSocket.add(message); | |
65 webSocket.close(); | |
66 }); | |
67 webSocket.add("Hello World"); | |
68 }); | |
69 }); | |
70 | |
71 var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/'; | |
72 WebSocket.connect(url, compression: clientOptions).then((websocket) { | |
73 var future = websocket.listen((message) { | |
74 Expect.equals("Hello World", message); | |
75 }).asFuture(); | |
76 websocket.add("Hello World"); | |
77 return future; | |
78 }).then((_) { | |
79 server.close(); | |
80 asyncEnd(); | |
81 }); | |
82 }); | |
83 } | |
84 | |
85 void testCompressionHeaders() { | |
86 asyncStart(); | |
87 createServer().then((server) { | |
88 server.listen((request) { | |
89 Expect.equals('Upgrade', request.headers.value(HttpHeaders.CONNECTION)); | |
90 Expect.equals('websocket', request.headers.value(HttpHeaders.UPGRADE)); | |
91 | |
92 var key = request.headers.value('Sec-WebSocket-Key'); | |
93 var sha1 = new SHA1()..add("$key$WEB_SOCKET_GUID".codeUnits); | |
94 var accept = CryptoUtils.bytesToBase64(sha1.close()); | |
95 request.response | |
96 ..statusCode = HttpStatus.SWITCHING_PROTOCOLS | |
97 ..headers.add(HttpHeaders.CONNECTION, "Upgrade") | |
98 ..headers.add(HttpHeaders.UPGRADE, "websocket") | |
99 ..headers.add("Sec-WebSocket-Accept", accept) | |
100 ..headers.add("Sec-WebSocket-Extensions", | |
101 "permessage-deflate;" | |
102 // Test quoted values and space padded = | |
103 'server_max_window_bits="10"; client_max_window_bits = 12' | |
104 'client_no_context_takeover; server_no_context_takeover'); | |
105 request.response.contentLength = 0; | |
106 request.response.detachSocket().then((socket) { | |
107 return new WebSocket.fromUpgradedSocket(socket, serverSide: true); | |
108 }).then((websocket) { | |
109 websocket.add("Hello"); | |
110 websocket.close(); | |
111 asyncEnd(); | |
112 }); | |
113 }); | |
114 | |
115 var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/'; | |
116 | |
117 WebSocket.connect(url).then((websocket) { | |
118 return websocket.listen((message) { | |
119 Expect.equals("Hello", message); | |
120 websocket.close(); | |
121 }).asFuture(); | |
122 }).then((_) => server.close()); | |
123 }); | |
124 } | |
125 | |
126 void runTests() { | |
127 // No compression or takeover | |
128 testCompressionSupport(); | |
129 // compression no takeover | |
130 testCompressionSupport(server: true, client: true); | |
131 // compression and context takeover. | |
132 testCompressionSupport(server: true, client: true, contextTakeover: true); | |
133 // Compression on client but not server. No take over | |
134 testCompressionSupport(client: true); | |
135 // Compression on server but not client. | |
136 testCompressionSupport(server: true); | |
137 | |
138 testCompressionHeaders(); | |
139 } | |
140 } | |
141 | |
142 main() { | |
143 new SecurityConfiguration(secure: false).runTests(); | |
144 // TODO(whesse): Make WebSocket.connect() take an optional context: parameter. | |
145 // new SecurityConfiguration(secure: true).runTests(); | |
146 } | |
OLD | NEW |