| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart.io; | 5 library dart.io; |
| 6 | 6 |
| 7 import "package:async_helper/async_helper.dart"; | 7 import "package:async_helper/async_helper.dart"; |
| 8 import "package:expect/expect.dart"; | 8 import "package:expect/expect.dart"; |
| 9 import "dart:async"; | 9 import "dart:async"; |
| 10 import "dart:collection"; | 10 import "dart:collection"; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 class WebSocketMessageCollector { | 53 class WebSocketMessageCollector { |
| 54 List<int> expectedMessage; | 54 List<int> expectedMessage; |
| 55 | 55 |
| 56 int messageCount = 0; | 56 int messageCount = 0; |
| 57 | 57 |
| 58 var data; | 58 var data; |
| 59 | 59 |
| 60 Function onClosed; | 60 Function onClosed; |
| 61 | 61 |
| 62 WebSocketMessageCollector(Stream stream, | 62 WebSocketMessageCollector(Stream stream, |
| 63 [List<int> this.expectedMessage = null]) { | 63 [List<int> this.expectedMessage = null]) { |
| 64 stream.listen(onMessageData, onDone: onClosed, onError: onError); | 64 stream.listen(onMessageData, onDone: onClosed, onError: onError); |
| 65 } | 65 } |
| 66 | 66 |
| 67 void onMessageData(buffer) { | 67 void onMessageData(buffer) { |
| 68 if (buffer is String) { | 68 if (buffer is String) { |
| 69 buffer = UTF8.encode(buffer); | 69 buffer = UTF8.encode(buffer); |
| 70 } | 70 } |
| 71 Expect.listEquals(expectedMessage, buffer); | 71 Expect.listEquals(expectedMessage, buffer); |
| 72 messageCount++; | 72 messageCount++; |
| 73 data = buffer; | 73 data = buffer; |
| 74 } | 74 } |
| 75 | 75 |
| 76 void onError(e, trace) { | 76 void onError(e, trace) { |
| 77 String msg = "Unexpected error $e"; | 77 String msg = "Unexpected error $e"; |
| 78 if (trace != null) msg += "\nStackTrace: $trace"; | 78 if (trace != null) msg += "\nStackTrace: $trace"; |
| 79 Expect.fail(msg); | 79 Expect.fail(msg); |
| 80 } | 80 } |
| 81 | |
| 82 } | 81 } |
| 83 | 82 |
| 84 | |
| 85 // Web socket constants. | 83 // Web socket constants. |
| 86 const int FRAME_OPCODE_TEXT = 1; | 84 const int FRAME_OPCODE_TEXT = 1; |
| 87 const int FRAME_OPCODE_BINARY = 2; | 85 const int FRAME_OPCODE_BINARY = 2; |
| 88 | 86 |
| 89 | |
| 90 // Function for building a web socket frame. | 87 // Function for building a web socket frame. |
| 91 List<int> createFrame(bool fin, | 88 List<int> createFrame(bool fin, int opcode, int maskingKey, List<int> data, |
| 92 int opcode, | 89 int offset, int count) { |
| 93 int maskingKey, | |
| 94 List<int> data, | |
| 95 int offset, | |
| 96 int count) { | |
| 97 int frameSize = 2; | 90 int frameSize = 2; |
| 98 if (count > 125) frameSize += 2; | 91 if (count > 125) frameSize += 2; |
| 99 if (count > 65535) frameSize += 6; | 92 if (count > 65535) frameSize += 6; |
| 100 frameSize += count; | 93 frameSize += count; |
| 101 // No masking. | 94 // No masking. |
| 102 assert(maskingKey == null); | 95 assert(maskingKey == null); |
| 103 List<int> frame = new Uint8List(frameSize); | 96 List<int> frame = new Uint8List(frameSize); |
| 104 int frameIndex = 0; | 97 int frameIndex = 0; |
| 105 frame[frameIndex++] = (fin ? 0x80 : 0x00) | opcode; | 98 frame[frameIndex++] = (fin ? 0x80 : 0x00) | opcode; |
| 106 if (count < 126) { | 99 if (count < 126) { |
| 107 frame[frameIndex++] = count; | 100 frame[frameIndex++] = count; |
| 108 } else if (count < 65536) { | 101 } else if (count < 65536) { |
| 109 frame[frameIndex++] = 126; | 102 frame[frameIndex++] = 126; |
| 110 frame[frameIndex++] = count >> 8; | 103 frame[frameIndex++] = count >> 8; |
| 111 frame[frameIndex++] = count & 0xFF; | 104 frame[frameIndex++] = count & 0xFF; |
| 112 } else { | 105 } else { |
| 113 frame[frameIndex++] = 127; | 106 frame[frameIndex++] = 127; |
| 114 for (int i = 0; i < 8; i++) { | 107 for (int i = 0; i < 8; i++) { |
| 115 frame[frameIndex++] = count >> ((7 - i) * 8) & 0xFF; | 108 frame[frameIndex++] = count >> ((7 - i) * 8) & 0xFF; |
| 116 } | 109 } |
| 117 } | 110 } |
| 118 frame.setRange(frameIndex, frameIndex + count, data, offset); | 111 frame.setRange(frameIndex, frameIndex + count, data, offset); |
| 119 return frame; | 112 return frame; |
| 120 } | 113 } |
| 121 | 114 |
| 122 | |
| 123 // Test processing messages which are sent in a single frame. | 115 // Test processing messages which are sent in a single frame. |
| 124 void testFullMessages() { | 116 void testFullMessages() { |
| 125 void testMessage(int opcode, List<int> message) { | 117 void testMessage(int opcode, List<int> message) { |
| 126 int messageCount = 0; | 118 int messageCount = 0; |
| 127 // Use the same web socket protocol transformer for all frames. | 119 // Use the same web socket protocol transformer for all frames. |
| 128 var transformer = new _WebSocketProtocolTransformer(); | 120 var transformer = new _WebSocketProtocolTransformer(); |
| 129 var controller = new StreamController(sync: true); | 121 var controller = new StreamController(sync: true); |
| 130 WebSocketMessageCollector mc = new WebSocketMessageCollector( | 122 WebSocketMessageCollector mc = new WebSocketMessageCollector( |
| 131 controller.stream.transform(transformer), | 123 controller.stream.transform(transformer), message); |
| 132 message); | |
| 133 | 124 |
| 134 List<int> frame = createFrame( | 125 List<int> frame = |
| 135 true, opcode, null, message, 0, message.length); | 126 createFrame(true, opcode, null, message, 0, message.length); |
| 136 | 127 |
| 137 // Update the transformer with one big chunk. | 128 // Update the transformer with one big chunk. |
| 138 messageCount++; | 129 messageCount++; |
| 139 controller.add(frame); | 130 controller.add(frame); |
| 140 mc.onClosed = () { | 131 mc.onClosed = () { |
| 141 Expect.isNotNull(mc.data); | 132 Expect.isNotNull(mc.data); |
| 142 Expect.equals(0, transformer._state); | 133 Expect.equals(0, transformer._state); |
| 143 | 134 |
| 144 mc.data = null; | 135 mc.data = null; |
| 145 | 136 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 } | 169 } |
| 179 } | 170 } |
| 180 | 171 |
| 181 // Test different message sizes. | 172 // Test different message sizes. |
| 182 runTest(0, 10, 1); | 173 runTest(0, 10, 1); |
| 183 runTest(120, 130, 1); | 174 runTest(120, 130, 1); |
| 184 runTest(0, 1000, 100); | 175 runTest(0, 1000, 100); |
| 185 runTest(65534, 65537, 1); | 176 runTest(65534, 65537, 1); |
| 186 } | 177 } |
| 187 | 178 |
| 188 | |
| 189 // Test processing of frames which are split into fragments. | 179 // Test processing of frames which are split into fragments. |
| 190 void testFragmentedMessages() { | 180 void testFragmentedMessages() { |
| 191 // Use the same web socket protocol transformer for all frames. | 181 // Use the same web socket protocol transformer for all frames. |
| 192 var transformer = new _WebSocketProtocolTransformer(); | 182 var transformer = new _WebSocketProtocolTransformer(); |
| 193 var controller = new StreamController(sync: true); | 183 var controller = new StreamController(sync: true); |
| 194 WebSocketMessageCollector mc = new WebSocketMessageCollector( | 184 WebSocketMessageCollector mc = |
| 195 controller.stream.transform(transformer)); | 185 new WebSocketMessageCollector(controller.stream.transform(transformer)); |
| 196 | 186 |
| 197 int messageCount = 0; | 187 int messageCount = 0; |
| 198 int frameCount = 0; | 188 int frameCount = 0; |
| 199 | 189 |
| 200 void testFragmentMessage(int opcode, List<int> message, int fragmentSize) { | 190 void testFragmentMessage(int opcode, List<int> message, int fragmentSize) { |
| 201 messageCount++; | 191 messageCount++; |
| 202 int messageIndex = 0; | 192 int messageIndex = 0; |
| 203 int remaining = message.length; | 193 int remaining = message.length; |
| 204 bool firstFrame = true; | 194 bool firstFrame = true; |
| 205 bool lastFrame = false; | 195 bool lastFrame = false; |
| 206 while (!lastFrame) { | 196 while (!lastFrame) { |
| 207 int payloadSize = min(fragmentSize, remaining); | 197 int payloadSize = min(fragmentSize, remaining); |
| 208 lastFrame = payloadSize == remaining; | 198 lastFrame = payloadSize == remaining; |
| 209 List<int> frame = createFrame(lastFrame, | 199 List<int> frame = createFrame(lastFrame, firstFrame ? opcode : 0x00, null, |
| 210 firstFrame ? opcode : 0x00, | 200 message, messageIndex, payloadSize); |
| 211 null, | |
| 212 message, | |
| 213 messageIndex, | |
| 214 payloadSize); | |
| 215 frameCount++; | 201 frameCount++; |
| 216 messageIndex += payloadSize; | 202 messageIndex += payloadSize; |
| 217 controller.add(frame); | 203 controller.add(frame); |
| 218 remaining -= payloadSize; | 204 remaining -= payloadSize; |
| 219 firstFrame = false; | 205 firstFrame = false; |
| 220 } | 206 } |
| 221 } | 207 } |
| 222 | 208 |
| 223 void testMessageFragmentation(int opcode, List<int> message) { | 209 void testMessageFragmentation(int opcode, List<int> message) { |
| 224 mc.expectedMessage = message; | 210 mc.expectedMessage = message; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 254 } | 240 } |
| 255 | 241 |
| 256 void testUnmaskedMessage() { | 242 void testUnmaskedMessage() { |
| 257 var transformer = new _WebSocketProtocolTransformer(true); | 243 var transformer = new _WebSocketProtocolTransformer(true); |
| 258 var controller = new StreamController(sync: true); | 244 var controller = new StreamController(sync: true); |
| 259 asyncStart(); | 245 asyncStart(); |
| 260 controller.stream.transform(transformer).listen((_) {}, onError: (e) { | 246 controller.stream.transform(transformer).listen((_) {}, onError: (e) { |
| 261 asyncEnd(); | 247 asyncEnd(); |
| 262 }); | 248 }); |
| 263 var message = new Uint8List(10); | 249 var message = new Uint8List(10); |
| 264 List<int> frame = createFrame( | 250 List<int> frame = |
| 265 true, FRAME_OPCODE_BINARY, null, message, 0, message.length); | 251 createFrame(true, FRAME_OPCODE_BINARY, null, message, 0, message.length); |
| 266 controller.add(frame); | 252 controller.add(frame); |
| 267 } | 253 } |
| 268 | 254 |
| 269 | |
| 270 void main() { | 255 void main() { |
| 271 testFullMessages(); | 256 testFullMessages(); |
| 272 testFragmentedMessages(); | 257 testFragmentedMessages(); |
| 273 testUnmaskedMessage(); | 258 testUnmaskedMessage(); |
| 274 } | 259 } |
| OLD | NEW |