| 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 #source("../../../../runtime/bin/http_parser.dart"); | 5 #source("../../../../runtime/bin/http_parser.dart"); |
| 6 | 6 |
| 7 class HttpParserTest { | 7 class HttpParserTest { |
| 8 static void runAllTests() { | 8 static void runAllTests() { |
| 9 testParseRequest(); | 9 testParseRequest(); |
| 10 testParseResponse(); | 10 testParseResponse(); |
| 11 testParseInvalidRequest(); | 11 testParseInvalidRequest(); |
| 12 testParseInvalidResponse(); | 12 testParseInvalidResponse(); |
| 13 } | 13 } |
| 14 | 14 |
| 15 static void _testParseRequest(String request, | 15 static void _testParseRequest(String request, |
| 16 String expectedMethod, | 16 String expectedMethod, |
| 17 String expectedUri, | 17 String expectedUri, |
| 18 [int expectedContentLength = -1, | 18 [int expectedContentLength = -1, |
| 19 int expectedBytesReceived = 0, | 19 int expectedBytesReceived = 0, |
| 20 Map expectedHeaders = null, | 20 Map expectedHeaders = null, |
| 21 bool chunked = false]) { | 21 bool chunked = false, |
| 22 bool upgrade = false, |
| 23 int unparsedLength = 0]) { |
| 22 _HttpParser httpParser; | 24 _HttpParser httpParser; |
| 23 bool headersCompleteCalled; | 25 bool headersCompleteCalled; |
| 24 bool dataEndCalled; | 26 bool dataEndCalled; |
| 25 String method; | 27 String method; |
| 26 String uri; | 28 String uri; |
| 27 Map headers; | 29 Map headers; |
| 28 int contentLength; | 30 int contentLength; |
| 29 int bytesReceived; | 31 int bytesReceived; |
| 30 | 32 |
| 31 void reset() { | 33 void reset() { |
| 32 httpParser = new _HttpParser(); | 34 httpParser = new _HttpParser(); |
| 33 httpParser.requestStart = (m, u) { method = m; uri = u; }; | 35 httpParser.requestStart = (m, u) { method = m; uri = u; }; |
| 34 httpParser.responseStart = (s, r) { Expect.fail("Expected request"); }; | 36 httpParser.responseStart = (s, r) { Expect.fail("Expected request"); }; |
| 35 httpParser.headerReceived = (f, v) { | 37 httpParser.headerReceived = (f, v) { |
| 36 Expect.isFalse(headersCompleteCalled); | 38 Expect.isFalse(headersCompleteCalled); |
| 37 headers[f] = v; | 39 headers[f] = v; |
| 38 }; | 40 }; |
| 39 httpParser.headersComplete = () { | 41 httpParser.headersComplete = () { |
| 40 Expect.isFalse(headersCompleteCalled); | 42 Expect.isFalse(headersCompleteCalled); |
| 41 if (!chunked) { | 43 if (!chunked) { |
| 42 Expect.equals(expectedContentLength, httpParser.contentLength); | 44 Expect.equals(expectedContentLength, httpParser.contentLength); |
| 43 } else { | 45 } else { |
| 44 Expect.equals(-1, httpParser.contentLength); | 46 Expect.equals(-1, httpParser.contentLength); |
| 45 } | 47 } |
| 46 if (expectedHeaders != null) { | 48 if (expectedHeaders != null) { |
| 47 expectedHeaders.forEach( | 49 expectedHeaders.forEach( |
| 48 (String name, String value) => | 50 (String name, String value) => |
| 49 Expect.equals(value, headers[name])); | 51 Expect.equals(value, headers[name])); |
| 50 } | 52 } |
| 53 Expect.equals(upgrade, httpParser.upgrade); |
| 51 headersCompleteCalled = true; | 54 headersCompleteCalled = true; |
| 52 }; | 55 }; |
| 53 httpParser.dataReceived = (List<int> data) { | 56 httpParser.dataReceived = (List<int> data) { |
| 54 Expect.isTrue(headersCompleteCalled); | 57 Expect.isTrue(headersCompleteCalled); |
| 55 bytesReceived += data.length; | 58 bytesReceived += data.length; |
| 56 }; | 59 }; |
| 57 httpParser.dataEnd = (close) { | 60 httpParser.dataEnd = (close) { |
| 58 Expect.isFalse(close); | 61 Expect.isFalse(close); |
| 59 dataEndCalled = true; | 62 dataEndCalled = true; |
| 60 }; | 63 }; |
| 61 | 64 |
| 62 headersCompleteCalled = false; | 65 headersCompleteCalled = false; |
| 63 dataEndCalled = false; | 66 dataEndCalled = false; |
| 64 method = null; | 67 method = null; |
| 65 uri = null; | 68 uri = null; |
| 66 headers = new Map(); | 69 headers = new Map(); |
| 67 bytesReceived = 0; | 70 bytesReceived = 0; |
| 68 } | 71 } |
| 69 | 72 |
| 70 void testWrite(List<int> requestData, [int chunkSize = -1]) { | 73 void testWrite(List<int> requestData, [int chunkSize = -1]) { |
| 71 if (chunkSize == -1) chunkSize = requestData.length; | 74 if (chunkSize == -1) chunkSize = requestData.length; |
| 72 reset(); | 75 reset(); |
| 76 int written = 0; |
| 77 int unparsed; |
| 73 for (int pos = 0; pos < requestData.length; pos += chunkSize) { | 78 for (int pos = 0; pos < requestData.length; pos += chunkSize) { |
| 74 int remaining = requestData.length - pos; | 79 int remaining = requestData.length - pos; |
| 75 int writeLength = Math.min(chunkSize, remaining); | 80 int writeLength = Math.min(chunkSize, remaining); |
| 76 httpParser.writeList(requestData, pos, writeLength); | 81 written += writeLength; |
| 82 int parsed = httpParser.writeList(requestData, pos, writeLength); |
| 83 unparsed = writeLength - parsed; |
| 84 if (httpParser.upgrade) { |
| 85 unparsed += requestData.length - written; |
| 86 break; |
| 87 } else { |
| 88 Expect.equals(0, unparsed); |
| 89 } |
| 77 } | 90 } |
| 78 Expect.equals(expectedMethod, method); | 91 Expect.equals(expectedMethod, method); |
| 79 Expect.equals(expectedUri, uri); | 92 Expect.equals(expectedUri, uri); |
| 80 Expect.isTrue(headersCompleteCalled); | 93 Expect.isTrue(headersCompleteCalled); |
| 81 Expect.equals(expectedBytesReceived, bytesReceived); | 94 Expect.equals(expectedBytesReceived, bytesReceived); |
| 82 Expect.isTrue(dataEndCalled); | 95 if (!upgrade) Expect.isTrue(dataEndCalled); |
| 96 if (unparsedLength == 0) { |
| 97 Expect.equals(0, unparsed); |
| 98 } else { |
| 99 Expect.equals(unparsedLength, unparsed); |
| 100 } |
| 83 } | 101 } |
| 84 | 102 |
| 85 // Test parsing the request three times delivering the data in | 103 // Test parsing the request three times delivering the data in |
| 86 // different chunks. | 104 // different chunks. |
| 87 List<int> requestData = request.charCodes(); | 105 List<int> requestData = request.charCodes(); |
| 88 testWrite(requestData); | 106 testWrite(requestData); |
| 89 testWrite(requestData, 10); | 107 testWrite(requestData, 10); |
| 90 testWrite(requestData, 1); | 108 testWrite(requestData, 1); |
| 91 } | 109 } |
| 92 | 110 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 | 143 |
| 126 static void _testParseResponse(String response, | 144 static void _testParseResponse(String response, |
| 127 int expectedStatusCode, | 145 int expectedStatusCode, |
| 128 String expectedReasonPhrase, | 146 String expectedReasonPhrase, |
| 129 [int expectedContentLength = -1, | 147 [int expectedContentLength = -1, |
| 130 int expectedBytesReceived = 0, | 148 int expectedBytesReceived = 0, |
| 131 Map expectedHeaders = null, | 149 Map expectedHeaders = null, |
| 132 bool chunked = false, | 150 bool chunked = false, |
| 133 bool close = false, | 151 bool close = false, |
| 134 String responseToMethod = null, | 152 String responseToMethod = null, |
| 135 bool connectionClose = false]) { | 153 bool connectionClose = false, |
| 154 bool upgrade = false, |
| 155 int unparsedLength = 0]) { |
| 136 _HttpParser httpParser; | 156 _HttpParser httpParser; |
| 137 bool headersCompleteCalled; | 157 bool headersCompleteCalled; |
| 138 bool dataEndCalled; | 158 bool dataEndCalled; |
| 139 bool dataEndClose; | 159 bool dataEndClose; |
| 140 int statusCode; | 160 int statusCode; |
| 141 String reasonPhrase; | 161 String reasonPhrase; |
| 142 Map headers; | 162 Map headers; |
| 143 int contentLength; | 163 int contentLength; |
| 144 int bytesReceived; | 164 int bytesReceived; |
| 145 | 165 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 162 if (!chunked && !close) { | 182 if (!chunked && !close) { |
| 163 Expect.equals(expectedContentLength, httpParser.contentLength); | 183 Expect.equals(expectedContentLength, httpParser.contentLength); |
| 164 } else { | 184 } else { |
| 165 Expect.equals(-1, httpParser.contentLength); | 185 Expect.equals(-1, httpParser.contentLength); |
| 166 } | 186 } |
| 167 if (expectedHeaders != null) { | 187 if (expectedHeaders != null) { |
| 168 expectedHeaders.forEach((String name, String value) { | 188 expectedHeaders.forEach((String name, String value) { |
| 169 Expect.equals(value, headers[name]); | 189 Expect.equals(value, headers[name]); |
| 170 }); | 190 }); |
| 171 } | 191 } |
| 192 Expect.equals(upgrade, httpParser.upgrade); |
| 172 headersCompleteCalled = true; | 193 headersCompleteCalled = true; |
| 173 }; | 194 }; |
| 174 httpParser.dataReceived = (List<int> data) { | 195 httpParser.dataReceived = (List<int> data) { |
| 175 Expect.isTrue(headersCompleteCalled); | 196 Expect.isTrue(headersCompleteCalled); |
| 176 bytesReceived += data.length; | 197 bytesReceived += data.length; |
| 177 }; | 198 }; |
| 178 httpParser.dataEnd = (close) { | 199 httpParser.dataEnd = (close) { |
| 179 dataEndCalled = true; | 200 dataEndCalled = true; |
| 180 dataEndClose = close; | 201 dataEndClose = close; |
| 181 }; | 202 }; |
| 182 | 203 |
| 183 headersCompleteCalled = false; | 204 headersCompleteCalled = false; |
| 184 dataEndCalled = false; | 205 dataEndCalled = false; |
| 185 dataEndClose = null; | 206 dataEndClose = null; |
| 186 statusCode = -1; | 207 statusCode = -1; |
| 187 reasonPhrase = null; | 208 reasonPhrase = null; |
| 188 headers = new Map(); | 209 headers = new Map(); |
| 189 bytesReceived = 0; | 210 bytesReceived = 0; |
| 190 } | 211 } |
| 191 | 212 |
| 192 void testWrite(List<int> requestData, [int chunkSize = -1]) { | 213 void testWrite(List<int> requestData, [int chunkSize = -1]) { |
| 193 if (chunkSize == -1) chunkSize = requestData.length; | 214 if (chunkSize == -1) chunkSize = requestData.length; |
| 194 reset(); | 215 reset(); |
| 216 int written = 0; |
| 217 int unparsed; |
| 195 for (int pos = 0; pos < requestData.length; pos += chunkSize) { | 218 for (int pos = 0; pos < requestData.length; pos += chunkSize) { |
| 196 int remaining = requestData.length - pos; | 219 int remaining = requestData.length - pos; |
| 197 int writeLength = Math.min(chunkSize, remaining); | 220 int writeLength = Math.min(chunkSize, remaining); |
| 198 httpParser.writeList(requestData, pos, writeLength); | 221 written += writeLength; |
| 222 int parsed = httpParser.writeList(requestData, pos, writeLength); |
| 223 unparsed = writeLength - parsed; |
| 224 if (httpParser.upgrade) { |
| 225 unparsed += requestData.length - written; |
| 226 break; |
| 227 } else { |
| 228 Expect.equals(0, unparsed); |
| 229 } |
| 199 } | 230 } |
| 200 if (close) httpParser.connectionClosed(); | 231 if (close) httpParser.connectionClosed(); |
| 201 Expect.equals(expectedStatusCode, statusCode); | 232 Expect.equals(expectedStatusCode, statusCode); |
| 202 Expect.equals(expectedReasonPhrase, reasonPhrase); | 233 Expect.equals(expectedReasonPhrase, reasonPhrase); |
| 203 Expect.isTrue(headersCompleteCalled); | 234 Expect.isTrue(headersCompleteCalled); |
| 204 Expect.equals(expectedBytesReceived, bytesReceived); | 235 Expect.equals(expectedBytesReceived, bytesReceived); |
| 205 Expect.isTrue(dataEndCalled); | 236 if (!upgrade) { |
| 206 if (close) Expect.isTrue(dataEndClose); | 237 Expect.isTrue(dataEndCalled); |
| 207 Expect.equals(dataEndClose, connectionClose); | 238 if (close) Expect.isTrue(dataEndClose); |
| 239 Expect.equals(dataEndClose, connectionClose); |
| 240 } |
| 241 if (unparsedLength == 0) { |
| 242 Expect.equals(0, unparsed); |
| 243 } else { |
| 244 Expect.equals(unparsedLength, unparsed); |
| 245 } |
| 208 } | 246 } |
| 209 | 247 |
| 210 // Test parsing the request three times delivering the data in | 248 // Test parsing the request three times delivering the data in |
| 211 // different chunks. | 249 // different chunks. |
| 212 List<int> responseData = response.charCodes(); | 250 List<int> responseData = response.charCodes(); |
| 213 testWrite(responseData); | 251 testWrite(responseData); |
| 214 testWrite(responseData, 10); | 252 testWrite(responseData, 10); |
| 215 testWrite(responseData, 1); | 253 testWrite(responseData, 1); |
| 216 } | 254 } |
| 217 | 255 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 _testParseRequest(request, | 381 _testParseRequest(request, |
| 344 "POST", | 382 "POST", |
| 345 "/test", | 383 "/test", |
| 346 expectedContentLength: 10, | 384 expectedContentLength: 10, |
| 347 expectedBytesReceived: 10); | 385 expectedBytesReceived: 10); |
| 348 | 386 |
| 349 // Test connection close header. | 387 // Test connection close header. |
| 350 request = """ | 388 request = """ |
| 351 GET /test HTTP/1.1\r | 389 GET /test HTTP/1.1\r |
| 352 Connection: close\r | 390 Connection: close\r |
| 353 \r | 391 \r\n"""; |
| 354 """; | |
| 355 _testParseRequest(request, "GET", "/test"); | 392 _testParseRequest(request, "GET", "/test"); |
| 356 | 393 |
| 357 // Test chunked encoding. | 394 // Test chunked encoding. |
| 358 request = """ | 395 request = """ |
| 359 POST /test HTTP/1.1\r | 396 POST /test HTTP/1.1\r |
| 360 Transfer-Encoding: chunked\r | 397 Transfer-Encoding: chunked\r |
| 361 \r | 398 \r |
| 362 5\r | 399 5\r |
| 363 01234\r | 400 01234\r |
| 364 5\r | 401 5\r |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 012345678901234567890123456789\r | 472 012345678901234567890123456789\r |
| 436 1E;yyy=zzz\r | 473 1E;yyy=zzz\r |
| 437 012345678901234567890123456789\r | 474 012345678901234567890123456789\r |
| 438 0\r\n\r\n"""; | 475 0\r\n\r\n"""; |
| 439 _testParseRequest(request, | 476 _testParseRequest(request, |
| 440 "POST", | 477 "POST", |
| 441 "/test", | 478 "/test", |
| 442 expectedContentLength: -1, | 479 expectedContentLength: -1, |
| 443 expectedBytesReceived: 60, | 480 expectedBytesReceived: 60, |
| 444 chunked: true); | 481 chunked: true); |
| 482 |
| 483 // Test HTTP upgrade. |
| 484 request = """ |
| 485 GET /irc HTTP/1.1\r |
| 486 Upgrade: irc/1.2\r |
| 487 Connection: Upgrade\r |
| 488 \r\n\x01\x01\x01\x01\x01\x02\x02\x02\x02\xFF"""; |
| 489 headers = new Map(); |
| 490 headers["upgrade"] = "irc/1.2"; |
| 491 _testParseRequest(request, |
| 492 "GET", |
| 493 "/irc", |
| 494 expectedHeaders: headers, |
| 495 upgrade: true, |
| 496 unparsedLength: 10); |
| 497 |
| 498 // Test HTTP upgrade with protocol data. |
| 499 request = """ |
| 500 GET /irc HTTP/1.1\r |
| 501 Upgrade: irc/1.2\r |
| 502 Connection: Upgrade\r |
| 503 \r\n"""; |
| 504 headers = new Map(); |
| 505 headers["upgrade"] = "irc/1.2"; |
| 506 _testParseRequest(request, |
| 507 "GET", |
| 508 "/irc", |
| 509 expectedHeaders: headers, |
| 510 upgrade: true); |
| 511 |
| 512 // Test websocket upgrade. |
| 513 request = """ |
| 514 GET /chat HTTP/1.1\r |
| 515 Host: server.example.com\r |
| 516 Upgrade: websocket\r |
| 517 Connection: Upgrade\r |
| 518 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r |
| 519 Origin: http://example.com\r |
| 520 Sec-WebSocket-Version: 13\r |
| 521 \r\n"""; |
| 522 headers = new Map(); |
| 523 headers["host"] = "server.example.com"; |
| 524 headers["upgrade"] = "websocket"; |
| 525 headers["sec-websocket-key"] = "dGhlIHNhbXBsZSBub25jZQ=="; |
| 526 headers["origin"] = "http://example.com"; |
| 527 headers["sec-websocket-version"] = "13"; |
| 528 _testParseRequest(request, |
| 529 "GET", |
| 530 "/chat", |
| 531 expectedHeaders: headers, |
| 532 upgrade: true); |
| 533 |
| 534 |
| 535 // Test websocket upgrade with protocol data. NOTE: When using the |
| 536 // WebSocket protocol this should never happen as the client |
| 537 // should not send protocol data before processing the request |
| 538 // part of the opening handshake. However the HTTP parser should |
| 539 // still handle this. |
| 540 request = """ |
| 541 GET /chat HTTP/1.1\r |
| 542 Host: server.example.com\r |
| 543 Upgrade: websocket\r |
| 544 Connection: Upgrade\r |
| 545 Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r |
| 546 Origin: http://example.com\r |
| 547 Sec-WebSocket-Version: 13\r |
| 548 \r\n0123456"""; |
| 549 headers = new Map(); |
| 550 headers["host"] = "server.example.com"; |
| 551 headers["upgrade"] = "websocket"; |
| 552 headers["sec-websocket-key"] = "dGhlIHNhbXBsZSBub25jZQ=="; |
| 553 headers["origin"] = "http://example.com"; |
| 554 headers["sec-websocket-version"] = "13"; |
| 555 _testParseRequest(request, |
| 556 "GET", |
| 557 "/chat", |
| 558 expectedHeaders: headers, |
| 559 upgrade: true, |
| 560 unparsedLength: 7); |
| 445 } | 561 } |
| 446 | 562 |
| 447 static void testParseResponse() { | 563 static void testParseResponse() { |
| 448 String response; | 564 String response; |
| 449 Map headers; | 565 Map headers; |
| 450 response = "HTTP/1.1 100 Continue\r\nContent-Length: 0\r\n\r\n"; | 566 response = "HTTP/1.1 100 Continue\r\nContent-Length: 0\r\n\r\n"; |
| 451 _testParseResponse(response, 100, "Continue", expectedContentLength: 0); | 567 _testParseResponse(response, 100, "Continue", expectedContentLength: 0); |
| 452 | 568 |
| 453 response = "HTTP/1.1 100 Continue\r\nContent-Length: 10\r\n\r\n"; | 569 response = "HTTP/1.1 100 Continue\r\nContent-Length: 10\r\n\r\n"; |
| 454 _testParseResponse(response, | 570 _testParseResponse(response, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 "OK", | 640 "OK", |
| 525 expectedContentLength: -1, | 641 expectedContentLength: -1, |
| 526 expectedBytesReceived: 57, | 642 expectedBytesReceived: 57, |
| 527 chunked: true); | 643 chunked: true); |
| 528 | 644 |
| 529 // Test connection close header. | 645 // Test connection close header. |
| 530 response = """ | 646 response = """ |
| 531 HTTP/1.1 200 OK\r | 647 HTTP/1.1 200 OK\r |
| 532 Content-Length: 0\r | 648 Content-Length: 0\r |
| 533 Connection: close\r | 649 Connection: close\r |
| 534 \r | 650 \r\n"""; |
| 535 """; | |
| 536 _testParseResponse(response, | 651 _testParseResponse(response, |
| 537 200, | 652 200, |
| 538 "OK", | 653 "OK", |
| 539 expectedContentLength: 0, | 654 expectedContentLength: 0, |
| 540 connectionClose: true); | 655 connectionClose: true); |
| 541 | 656 |
| 542 // Test HTTP response without any transfer length indications | 657 // Test HTTP response without any transfer length indications |
| 543 // where closing the connections indicates end of body. | 658 // where closing the connections indicates end of body. |
| 544 response = """ | 659 response = """ |
| 545 HTTP/1.1 200 OK\r | 660 HTTP/1.1 200 OK\r |
| 546 \r | 661 \r |
| 547 01234567890123456789012345 | 662 01234567890123456789012345 |
| 548 0123456789012345678901234567890 | 663 0123456789012345678901234567890 |
| 549 """; | 664 """; |
| 550 _testParseResponse(response, | 665 _testParseResponse(response, |
| 551 200, | 666 200, |
| 552 "OK", | 667 "OK", |
| 553 expectedContentLength: -1, | 668 expectedContentLength: -1, |
| 554 expectedBytesReceived: 59, | 669 expectedBytesReceived: 59, |
| 555 close: true, | 670 close: true, |
| 556 connectionClose: true); | 671 connectionClose: true); |
| 672 |
| 673 // Test HTTP upgrade. |
| 674 response = """ |
| 675 HTTP/1.1 101 Switching Protocols\r |
| 676 Upgrade: irc/1.2\r |
| 677 Connection: Upgrade\r |
| 678 \r\n"""; |
| 679 headers = new Map(); |
| 680 headers["upgrade"] = "irc/1.2"; |
| 681 _testParseResponse(response, |
| 682 101, |
| 683 "Switching Protocols", |
| 684 expectedHeaders: headers, |
| 685 upgrade: true); |
| 686 |
| 687 // Test HTTP upgrade with protocol data. |
| 688 response = """ |
| 689 HTTP/1.1 101 Switching Protocols\r |
| 690 Upgrade: irc/1.2\r |
| 691 Connection: Upgrade\r |
| 692 \r\n\x00\x10\x20\x30\x40\x50\x60\x70\x80\x90\xA0\xB0\xC0\xD0\xE0\xF0"""; |
| 693 headers = new Map(); |
| 694 headers["upgrade"] = "irc/1.2"; |
| 695 _testParseResponse(response, |
| 696 101, |
| 697 "Switching Protocols", |
| 698 expectedHeaders: headers, |
| 699 upgrade: true, |
| 700 unparsedLength: 16); |
| 701 |
| 702 // Test websocket upgrade. |
| 703 response = """ |
| 704 HTTP/1.1 101 Switching Protocols\r |
| 705 Upgrade: websocket\r |
| 706 Connection: Upgrade\r |
| 707 Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r |
| 708 \r\n"""; |
| 709 headers = new Map(); |
| 710 headers["upgrade"] = "websocket"; |
| 711 headers["sec-websocket-accept"] = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="; |
| 712 _testParseResponse(response, |
| 713 101, |
| 714 "Switching Protocols", |
| 715 expectedHeaders: headers, |
| 716 upgrade: true); |
| 717 |
| 718 // Test websocket upgrade with protocol data. |
| 719 response = """ |
| 720 HTTP/1.1 101 Switching Protocols\r |
| 721 Upgrade: websocket\r |
| 722 Connection: Upgrade\r |
| 723 Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r |
| 724 \r\nABCD"""; |
| 725 headers = new Map(); |
| 726 headers["upgrade"] = "websocket"; |
| 727 headers["sec-websocket-accept"] = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="; |
| 728 _testParseResponse(response, |
| 729 101, |
| 730 "Switching Protocols", |
| 731 expectedHeaders: headers, |
| 732 upgrade: true, |
| 733 unparsedLength: 4); |
| 557 } | 734 } |
| 558 | 735 |
| 559 static void testParseInvalidRequest() { | 736 static void testParseInvalidRequest() { |
| 560 String request; | 737 String request; |
| 561 request = "GET /\r\n\r\n"; | 738 request = "GET /\r\n\r\n"; |
| 562 _testParseInvalidRequest(request); | 739 _testParseInvalidRequest(request); |
| 563 | 740 |
| 564 request = "GET / \r\n\r\n"; | 741 request = "GET / \r\n\r\n"; |
| 565 _testParseInvalidRequest(request); | 742 _testParseInvalidRequest(request); |
| 566 | 743 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 0123456789012345678901234567890\r | 816 0123456789012345678901234567890\r |
| 640 0\r\n\r\n"""; | 817 0\r\n\r\n"""; |
| 641 _testParseInvalidResponse(response); | 818 _testParseInvalidResponse(response); |
| 642 } | 819 } |
| 643 } | 820 } |
| 644 | 821 |
| 645 | 822 |
| 646 void main() { | 823 void main() { |
| 647 HttpParserTest.runAllTests(); | 824 HttpParserTest.runAllTests(); |
| 648 } | 825 } |
| OLD | NEW |