OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
8 import "dart:async"; | 8 import "dart:async"; |
9 import "dart:collection"; | 9 import "dart:collection"; |
10 import "dart:convert"; | 10 import "dart:convert"; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 143 } |
144 | 144 |
145 // Test parsing the request three times delivering the data in | 145 // Test parsing the request three times delivering the data in |
146 // different chunks. | 146 // different chunks. |
147 List<int> requestData = new Uint8List.fromList(request.codeUnits); | 147 List<int> requestData = new Uint8List.fromList(request.codeUnits); |
148 testWrite(requestData); | 148 testWrite(requestData); |
149 testWrite(requestData, 10); | 149 testWrite(requestData, 10); |
150 testWrite(requestData, 1); | 150 testWrite(requestData, 1); |
151 } | 151 } |
152 | 152 |
| 153 static void _testParseRequestLean(String request, |
| 154 String expectedMethod, |
| 155 String expectedUri, |
| 156 {int expectedTransferLength: 0, |
| 157 int expectedBytesReceived: 0, |
| 158 Map expectedHeaders: null, |
| 159 bool chunked: false, |
| 160 bool upgrade: false, |
| 161 int unparsedLength: 0, |
| 162 bool connectionClose: false, |
| 163 String expectedVersion: "1.1"}) { |
| 164 _testParseRequest(request, |
| 165 expectedMethod, |
| 166 expectedUri, |
| 167 expectedTransferLength: expectedTransferLength, |
| 168 expectedBytesReceived: expectedBytesReceived, |
| 169 expectedHeaders: expectedHeaders, |
| 170 chunked: chunked, |
| 171 upgrade: upgrade, |
| 172 unparsedLength: unparsedLength, |
| 173 connectionClose: connectionClose, |
| 174 expectedVersion: expectedVersion); |
| 175 // Same test but with only \n instead of \r\n terminating each header line. |
| 176 _testParseRequest(request.replaceAll('\r', ''), |
| 177 expectedMethod, |
| 178 expectedUri, |
| 179 expectedTransferLength: expectedTransferLength, |
| 180 expectedBytesReceived: expectedBytesReceived, |
| 181 expectedHeaders: expectedHeaders, |
| 182 chunked: chunked, |
| 183 upgrade: upgrade, |
| 184 unparsedLength: unparsedLength, |
| 185 connectionClose: connectionClose, |
| 186 expectedVersion: expectedVersion); |
| 187 } |
| 188 |
153 static void _testParseInvalidRequest(String request) { | 189 static void _testParseInvalidRequest(String request) { |
154 _HttpParser httpParser; | 190 _HttpParser httpParser; |
155 bool errorCalled; | 191 bool errorCalled; |
156 StreamController controller; | 192 StreamController controller; |
157 | 193 |
158 void reset() { | 194 void reset() { |
159 httpParser = new _HttpParser.requestParser(); | 195 httpParser = new _HttpParser.requestParser(); |
160 controller = new StreamController(sync: true); | 196 controller = new StreamController(sync: true); |
161 var port = new ReceivePort(); | 197 var port = new ReceivePort(); |
162 httpParser.listenToStream(controller.stream); | 198 httpParser.listenToStream(controller.stream); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 Map headers; | 385 Map headers; |
350 var methods = [ | 386 var methods = [ |
351 // RFC 2616 methods. | 387 // RFC 2616 methods. |
352 "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", | 388 "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", |
353 // WebDAV methods from RFC 4918. | 389 // WebDAV methods from RFC 4918. |
354 "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", "LOCK", "UNLOCK", | 390 "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", "LOCK", "UNLOCK", |
355 // WebDAV methods from RFC 5323. | 391 // WebDAV methods from RFC 5323. |
356 "SEARCH", | 392 "SEARCH", |
357 // Methods with HTTP prefix. | 393 // Methods with HTTP prefix. |
358 "H", "HT", "HTT", "HTTP", "HX", "HTX", "HTTX", "HTTPX"]; | 394 "H", "HT", "HTT", "HTTP", "HX", "HTX", "HTTX", "HTTPX"]; |
| 395 methods = ['GET']; |
359 methods.forEach((method) { | 396 methods.forEach((method) { |
360 request = "$method / HTTP/1.1\r\n\r\n"; | 397 request = "$method / HTTP/1.1\r\n\r\n"; |
361 _testParseRequest(request, method, "/"); | 398 _testParseRequestLean(request, method, "/"); |
362 request = "$method /index.html HTTP/1.1\r\n\r\n"; | 399 request = "$method /index.html HTTP/1.1\r\n\r\n"; |
363 _testParseRequest(request, method, "/index.html"); | 400 _testParseRequestLean(request, method, "/index.html"); |
364 }); | 401 }); |
365 | |
366 request = "GET / HTTP/1.0\r\n\r\n"; | 402 request = "GET / HTTP/1.0\r\n\r\n"; |
367 _testParseRequest(request, "GET", "/", | 403 _testParseRequestLean(request, "GET", "/", |
368 expectedVersion: "1.0", | 404 expectedVersion: "1.0", |
369 connectionClose: true); | 405 connectionClose: true); |
370 | 406 |
371 request = "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n"; | 407 request = "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n"; |
372 _testParseRequest(request, "GET", "/", expectedVersion: "1.0"); | 408 _testParseRequestLean(request, "GET", "/", expectedVersion: "1.0"); |
373 | 409 |
374 request = """ | 410 request = """ |
375 POST /test HTTP/1.1\r | 411 POST /test HTTP/1.1\r |
376 AAA: AAA\r | 412 AAA: AAA\r |
377 \r | 413 \r |
378 """; | 414 """; |
379 _testParseRequest(request, "POST", "/test"); | 415 _testParseRequestLean(request, "POST", "/test"); |
380 | 416 |
381 request = """ | 417 request = """ |
382 POST /test HTTP/1.1\r | 418 POST /test HTTP/1.1\r |
383 \r | 419 \r |
384 """; | 420 """; |
385 _testParseRequest(request, "POST", "/test"); | 421 _testParseRequestLean(request, "POST", "/test"); |
386 | 422 |
387 request = """ | 423 request = """ |
388 POST /test HTTP/1.1\r | 424 POST /test HTTP/1.1\r |
389 Header-A: AAA\r | 425 Header-A: AAA\r |
390 X-Header-B: bbb\r | 426 X-Header-B: bbb\r |
391 \r | 427 \r |
392 """; | 428 """; |
393 headers = new Map(); | 429 headers = new Map(); |
394 headers["header-a"] = "AAA"; | 430 headers["header-a"] = "AAA"; |
395 headers["x-header-b"] = "bbb"; | 431 headers["x-header-b"] = "bbb"; |
396 _testParseRequest(request, "POST", "/test", expectedHeaders: headers); | 432 _testParseRequestLean(request, "POST", "/test", expectedHeaders: headers); |
397 | 433 |
398 request = """ | 434 request = """ |
399 POST /test HTTP/1.1\r | 435 POST /test HTTP/1.1\r |
400 Empty-Header-1:\r | 436 Empty-Header-1:\r |
401 Empty-Header-2:\r | 437 Empty-Header-2:\r |
402 \r | 438 \r |
403 \r | 439 \r |
404 """; | 440 """; |
405 headers = new Map(); | 441 headers = new Map(); |
406 headers["empty-header-1"] = ""; | 442 headers["empty-header-1"] = ""; |
407 headers["empty-header-2"] = ""; | 443 headers["empty-header-2"] = ""; |
408 _testParseRequest(request, "POST", "/test", expectedHeaders: headers); | 444 _testParseRequestLean(request, "POST", "/test", expectedHeaders: headers); |
409 | 445 |
410 request = """ | 446 request = """ |
411 POST /test HTTP/1.1\r | 447 POST /test HTTP/1.1\r |
412 Header-A: AAA\r | 448 Header-A: AAA\r |
413 X-Header-B:\t \t bbb\r | 449 X-Header-B:\t \t bbb\r |
414 \r | 450 \r |
415 """; | 451 """; |
416 headers = new Map(); | 452 headers = new Map(); |
417 headers["header-a"] = "AAA"; | 453 headers["header-a"] = "AAA"; |
418 headers["x-header-b"] = "bbb"; | 454 headers["x-header-b"] = "bbb"; |
419 _testParseRequest(request, "POST", "/test", expectedHeaders: headers); | 455 _testParseRequestLean(request, "POST", "/test", expectedHeaders: headers); |
420 | 456 |
421 request = """ | 457 request = """ |
422 POST /test HTTP/1.1\r | 458 POST /test HTTP/1.1\r |
423 Header-A: AA\r | 459 Header-A: AA\r |
424 A\r | 460 A\r |
425 X-Header-B: b\r | 461 X-Header-B: b\r |
426 b\r | 462 b\r |
427 \t b\r | 463 \t b\r |
428 \r | 464 \r |
429 """; | 465 """; |
430 | 466 |
431 headers = new Map(); | 467 headers = new Map(); |
432 headers["header-a"] = "AAA"; | 468 headers["header-a"] = "AAA"; |
433 headers["x-header-b"] = "bbb"; | 469 headers["x-header-b"] = "bbb"; |
434 _testParseRequest(request, "POST", "/test", expectedHeaders: headers); | 470 _testParseRequestLean(request, "POST", "/test", expectedHeaders: headers); |
435 | 471 |
436 request = """ | 472 request = """ |
437 POST /test HTTP/1.1\r | 473 POST /test HTTP/1.1\r |
438 Content-Length: 10\r | 474 Content-Length: 10\r |
439 \r | 475 \r |
440 0123456789"""; | 476 0123456789"""; |
441 _testParseRequest(request, | 477 _testParseRequestLean(request, |
442 "POST", | 478 "POST", |
443 "/test", | 479 "/test", |
444 expectedTransferLength: 10, | 480 expectedTransferLength: 10, |
445 expectedBytesReceived: 10); | 481 expectedBytesReceived: 10); |
446 | 482 |
447 // Test connection close header. | 483 // Test connection close header. |
448 request = "GET /test HTTP/1.1\r\nConnection: close\r\n\r\n"; | 484 request = "GET /test HTTP/1.1\r\nConnection: close\r\n\r\n"; |
449 _testParseRequest(request, "GET", "/test", connectionClose: true); | 485 _testParseRequest(request, "GET", "/test", connectionClose: true); |
450 | 486 |
451 // Test chunked encoding. | 487 // Test chunked encoding. |
452 request = """ | 488 request = """ |
453 POST /test HTTP/1.1\r | 489 POST /test HTTP/1.1\r |
454 Transfer-Encoding: chunked\r | 490 Transfer-Encoding: chunked\r |
455 \r | 491 \r |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 0123456789012345678901234567890\r | 928 0123456789012345678901234567890\r |
893 0\r\n\r\n"""; | 929 0\r\n\r\n"""; |
894 _testParseInvalidResponse(response); | 930 _testParseInvalidResponse(response); |
895 } | 931 } |
896 } | 932 } |
897 | 933 |
898 | 934 |
899 void main() { | 935 void main() { |
900 HttpParserTest.runAllTests(); | 936 HttpParserTest.runAllTests(); |
901 } | 937 } |
OLD | NEW |