| 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, | 22 bool upgrade = false, |
| 23 int unparsedLength = 0]) { | 23 int unparsedLength = 0, |
| 24 bool connectionClose = false, |
| 25 String expectedVersion = "1.1"]) { |
| 24 _HttpParser httpParser; | 26 _HttpParser httpParser; |
| 25 bool headersCompleteCalled; | 27 bool headersCompleteCalled; |
| 26 bool dataEndCalled; | 28 bool dataEndCalled; |
| 27 String method; | 29 String method; |
| 28 String uri; | 30 String uri; |
| 31 String version; |
| 29 Map headers; | 32 Map headers; |
| 30 int contentLength; | 33 int contentLength; |
| 31 int bytesReceived; | 34 int bytesReceived; |
| 32 | 35 |
| 33 void reset() { | 36 void reset() { |
| 34 httpParser = new _HttpParser(); | 37 httpParser = new _HttpParser(); |
| 35 httpParser.requestStart = (m, u) { method = m; uri = u; }; | 38 httpParser.requestStart = (m, u, v) { method = m; uri = u; version = v; }; |
| 36 httpParser.responseStart = (s, r) { Expect.fail("Expected request"); }; | 39 httpParser.responseStart = (s, r, v) { Expect.fail("Expected request"); }; |
| 37 httpParser.headerReceived = (f, v) { | 40 httpParser.headerReceived = (f, v) { |
| 38 Expect.isFalse(headersCompleteCalled); | 41 Expect.isFalse(headersCompleteCalled); |
| 39 headers[f] = v; | 42 headers[f] = v; |
| 40 }; | 43 }; |
| 41 httpParser.headersComplete = () { | 44 httpParser.headersComplete = () { |
| 42 Expect.isFalse(headersCompleteCalled); | 45 Expect.isFalse(headersCompleteCalled); |
| 43 if (!chunked) { | 46 if (!chunked) { |
| 44 Expect.equals(expectedContentLength, httpParser.contentLength); | 47 Expect.equals(expectedContentLength, httpParser.contentLength); |
| 45 } else { | 48 } else { |
| 46 Expect.equals(-1, httpParser.contentLength); | 49 Expect.equals(-1, httpParser.contentLength); |
| 47 } | 50 } |
| 48 if (expectedHeaders != null) { | 51 if (expectedHeaders != null) { |
| 49 expectedHeaders.forEach( | 52 expectedHeaders.forEach( |
| 50 (String name, String value) => | 53 (String name, String value) => |
| 51 Expect.equals(value, headers[name])); | 54 Expect.equals(value, headers[name])); |
| 52 } | 55 } |
| 53 Expect.equals(upgrade, httpParser.upgrade); | 56 Expect.equals(upgrade, httpParser.upgrade); |
| 57 Expect.equals(connectionClose, !httpParser.persistentConnection); |
| 54 headersCompleteCalled = true; | 58 headersCompleteCalled = true; |
| 55 }; | 59 }; |
| 56 httpParser.dataReceived = (List<int> data) { | 60 httpParser.dataReceived = (List<int> data) { |
| 57 Expect.isTrue(headersCompleteCalled); | 61 Expect.isTrue(headersCompleteCalled); |
| 58 bytesReceived += data.length; | 62 bytesReceived += data.length; |
| 59 }; | 63 }; |
| 60 httpParser.dataEnd = (close) { | 64 httpParser.dataEnd = (close) { |
| 61 Expect.isFalse(close); | 65 Expect.isFalse(close); |
| 62 dataEndCalled = true; | 66 dataEndCalled = true; |
| 63 }; | 67 }; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 83 unparsed = writeLength - parsed; | 87 unparsed = writeLength - parsed; |
| 84 if (httpParser.upgrade) { | 88 if (httpParser.upgrade) { |
| 85 unparsed += requestData.length - written; | 89 unparsed += requestData.length - written; |
| 86 break; | 90 break; |
| 87 } else { | 91 } else { |
| 88 Expect.equals(0, unparsed); | 92 Expect.equals(0, unparsed); |
| 89 } | 93 } |
| 90 } | 94 } |
| 91 Expect.equals(expectedMethod, method); | 95 Expect.equals(expectedMethod, method); |
| 92 Expect.equals(expectedUri, uri); | 96 Expect.equals(expectedUri, uri); |
| 97 Expect.equals(expectedVersion, version); |
| 93 Expect.isTrue(headersCompleteCalled); | 98 Expect.isTrue(headersCompleteCalled); |
| 94 Expect.equals(expectedBytesReceived, bytesReceived); | 99 Expect.equals(expectedBytesReceived, bytesReceived); |
| 95 if (!upgrade) Expect.isTrue(dataEndCalled); | 100 if (!upgrade) Expect.isTrue(dataEndCalled); |
| 96 if (unparsedLength == 0) { | 101 if (unparsedLength == 0) { |
| 97 Expect.equals(0, unparsed); | 102 Expect.equals(0, unparsed); |
| 98 } else { | 103 } else { |
| 99 Expect.equals(unparsedLength, unparsed); | 104 Expect.equals(unparsedLength, unparsed); |
| 100 } | 105 } |
| 101 } | 106 } |
| 102 | 107 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 int expectedStatusCode, | 150 int expectedStatusCode, |
| 146 String expectedReasonPhrase, | 151 String expectedReasonPhrase, |
| 147 [int expectedContentLength = -1, | 152 [int expectedContentLength = -1, |
| 148 int expectedBytesReceived = 0, | 153 int expectedBytesReceived = 0, |
| 149 Map expectedHeaders = null, | 154 Map expectedHeaders = null, |
| 150 bool chunked = false, | 155 bool chunked = false, |
| 151 bool close = false, | 156 bool close = false, |
| 152 String responseToMethod = null, | 157 String responseToMethod = null, |
| 153 bool connectionClose = false, | 158 bool connectionClose = false, |
| 154 bool upgrade = false, | 159 bool upgrade = false, |
| 155 int unparsedLength = 0]) { | 160 int unparsedLength = 0, |
| 161 String expectedVersion = "1.1"]) { |
| 156 _HttpParser httpParser; | 162 _HttpParser httpParser; |
| 157 bool headersCompleteCalled; | 163 bool headersCompleteCalled; |
| 158 bool dataEndCalled; | 164 bool dataEndCalled; |
| 159 bool dataEndClose; | 165 bool dataEndClose; |
| 160 int statusCode; | 166 int statusCode; |
| 161 String reasonPhrase; | 167 String reasonPhrase; |
| 168 String version; |
| 162 Map headers; | 169 Map headers; |
| 163 int contentLength; | 170 int contentLength; |
| 164 int bytesReceived; | 171 int bytesReceived; |
| 165 | 172 |
| 166 void reset() { | 173 void reset() { |
| 167 httpParser = new _HttpParser(); | 174 httpParser = new _HttpParser(); |
| 168 if (responseToMethod != null) { | 175 if (responseToMethod != null) { |
| 169 httpParser.responseToMethod = responseToMethod; | 176 httpParser.responseToMethod = responseToMethod; |
| 170 } | 177 } |
| 171 httpParser.requestStart = (m, u) => Expect.fail("Expected response"); | 178 httpParser.requestStart = (m, u, v) => Expect.fail("Expected response"); |
| 172 httpParser.responseStart = (s, r) { | 179 httpParser.responseStart = (s, r, v) { |
| 173 statusCode = s; | 180 statusCode = s; |
| 174 reasonPhrase = r; | 181 reasonPhrase = r; |
| 182 version = v; |
| 175 }; | 183 }; |
| 176 httpParser.headerReceived = (f, v) { | 184 httpParser.headerReceived = (f, v) { |
| 177 Expect.isFalse(headersCompleteCalled); | 185 Expect.isFalse(headersCompleteCalled); |
| 178 headers[f] = v; | 186 headers[f] = v; |
| 179 }; | 187 }; |
| 180 httpParser.headersComplete = () { | 188 httpParser.headersComplete = () { |
| 181 Expect.isFalse(headersCompleteCalled); | 189 Expect.isFalse(headersCompleteCalled); |
| 182 if (!chunked && !close) { | 190 if (!chunked && !close) { |
| 183 Expect.equals(expectedContentLength, httpParser.contentLength); | 191 Expect.equals(expectedContentLength, httpParser.contentLength); |
| 184 } else { | 192 } else { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 int parsed = httpParser.writeList(requestData, pos, writeLength); | 230 int parsed = httpParser.writeList(requestData, pos, writeLength); |
| 223 unparsed = writeLength - parsed; | 231 unparsed = writeLength - parsed; |
| 224 if (httpParser.upgrade) { | 232 if (httpParser.upgrade) { |
| 225 unparsed += requestData.length - written; | 233 unparsed += requestData.length - written; |
| 226 break; | 234 break; |
| 227 } else { | 235 } else { |
| 228 Expect.equals(0, unparsed); | 236 Expect.equals(0, unparsed); |
| 229 } | 237 } |
| 230 } | 238 } |
| 231 if (close) httpParser.connectionClosed(); | 239 if (close) httpParser.connectionClosed(); |
| 240 Expect.equals(expectedVersion, version); |
| 232 Expect.equals(expectedStatusCode, statusCode); | 241 Expect.equals(expectedStatusCode, statusCode); |
| 233 Expect.equals(expectedReasonPhrase, reasonPhrase); | 242 Expect.equals(expectedReasonPhrase, reasonPhrase); |
| 234 Expect.isTrue(headersCompleteCalled); | 243 Expect.isTrue(headersCompleteCalled); |
| 235 Expect.equals(expectedBytesReceived, bytesReceived); | 244 Expect.equals(expectedBytesReceived, bytesReceived); |
| 236 if (!upgrade) { | 245 if (!upgrade) { |
| 237 Expect.isTrue(dataEndCalled); | 246 Expect.isTrue(dataEndCalled); |
| 238 if (close) Expect.isTrue(dataEndClose); | 247 if (close) Expect.isTrue(dataEndClose); |
| 239 Expect.equals(dataEndClose, connectionClose); | 248 Expect.equals(dataEndClose, connectionClose); |
| 240 } | 249 } |
| 241 if (unparsedLength == 0) { | 250 if (unparsedLength == 0) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 | 314 |
| 306 request = "HT /index.html HTTP/1.1\r\n\r\n"; | 315 request = "HT /index.html HTTP/1.1\r\n\r\n"; |
| 307 _testParseRequest(request, "HT", "/index.html"); | 316 _testParseRequest(request, "HT", "/index.html"); |
| 308 | 317 |
| 309 request = "HTT /index.html HTTP/1.1\r\n\r\n"; | 318 request = "HTT /index.html HTTP/1.1\r\n\r\n"; |
| 310 _testParseRequest(request, "HTT", "/index.html"); | 319 _testParseRequest(request, "HTT", "/index.html"); |
| 311 | 320 |
| 312 request = "HTTP /index.html HTTP/1.1\r\n\r\n"; | 321 request = "HTTP /index.html HTTP/1.1\r\n\r\n"; |
| 313 _testParseRequest(request, "HTTP", "/index.html"); | 322 _testParseRequest(request, "HTTP", "/index.html"); |
| 314 | 323 |
| 324 request = "GET / HTTP/1.0\r\n\r\n"; |
| 325 _testParseRequest(request, "GET", "/", expectedVersion: "1.0", connectionClo
se: true); |
| 326 |
| 327 request = "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n"; |
| 328 _testParseRequest(request, "GET", "/", expectedVersion: "1.0"); |
| 329 |
| 315 request = """ | 330 request = """ |
| 316 POST /test HTTP/1.1\r | 331 POST /test HTTP/1.1\r |
| 317 AAA: AAA\r | 332 AAA: AAA\r |
| 318 \r | 333 \r |
| 319 """; | 334 """; |
| 320 _testParseRequest(request, "POST", "/test"); | 335 _testParseRequest(request, "POST", "/test"); |
| 321 | 336 |
| 322 request = """ | 337 request = """ |
| 323 POST /test HTTP/1.1\r | 338 POST /test HTTP/1.1\r |
| 324 \r | 339 \r |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 Content-Length: 10\r | 393 Content-Length: 10\r |
| 379 \r | 394 \r |
| 380 0123456789"""; | 395 0123456789"""; |
| 381 _testParseRequest(request, | 396 _testParseRequest(request, |
| 382 "POST", | 397 "POST", |
| 383 "/test", | 398 "/test", |
| 384 expectedContentLength: 10, | 399 expectedContentLength: 10, |
| 385 expectedBytesReceived: 10); | 400 expectedBytesReceived: 10); |
| 386 | 401 |
| 387 // Test connection close header. | 402 // Test connection close header. |
| 388 request = """ | 403 request = "GET /test HTTP/1.1\r\nConnection: close\r\n\r\n"; |
| 389 GET /test HTTP/1.1\r | 404 _testParseRequest(request, "GET", "/test", connectionClose: true); |
| 390 Connection: close\r | |
| 391 \r\n"""; | |
| 392 _testParseRequest(request, "GET", "/test"); | |
| 393 | 405 |
| 394 // Test chunked encoding. | 406 // Test chunked encoding. |
| 395 request = """ | 407 request = """ |
| 396 POST /test HTTP/1.1\r | 408 POST /test HTTP/1.1\r |
| 397 Transfer-Encoding: chunked\r | 409 Transfer-Encoding: chunked\r |
| 398 \r | 410 \r |
| 399 5\r | 411 5\r |
| 400 01234\r | 412 01234\r |
| 401 5\r | 413 5\r |
| 402 56789\r | 414 56789\r |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 response = "HTTP/1.1 100 Continue\r\nContent-Length: 0\r\n\r\n"; | 578 response = "HTTP/1.1 100 Continue\r\nContent-Length: 0\r\n\r\n"; |
| 567 _testParseResponse(response, 100, "Continue", expectedContentLength: 0); | 579 _testParseResponse(response, 100, "Continue", expectedContentLength: 0); |
| 568 | 580 |
| 569 response = "HTTP/1.1 100 Continue\r\nContent-Length: 10\r\n\r\n"; | 581 response = "HTTP/1.1 100 Continue\r\nContent-Length: 10\r\n\r\n"; |
| 570 _testParseResponse(response, | 582 _testParseResponse(response, |
| 571 100, | 583 100, |
| 572 "Continue", | 584 "Continue", |
| 573 expectedContentLength: 10, | 585 expectedContentLength: 10, |
| 574 expectedBytesReceived: 0); | 586 expectedBytesReceived: 0); |
| 575 | 587 |
| 588 response = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nConnection: Close\r\n\r\
n"; |
| 589 _testParseResponse(response, |
| 590 200, |
| 591 "OK", |
| 592 expectedContentLength: 0, |
| 593 connectionClose: true); |
| 594 |
| 595 response = "HTTP/1.0 200 OK\r\nContent-Length: 0\r\n\r\n"; |
| 596 _testParseResponse(response, |
| 597 200, |
| 598 "OK", |
| 599 expectedContentLength: 0, |
| 600 expectedVersion: "1.0", |
| 601 connectionClose: true); |
| 602 |
| 603 response = "HTTP/1.0 200 OK\r\nContent-Length: 0\r\nConnection: Keep-Alive\r
\n\r\n"; |
| 604 _testParseResponse(response, 200, "OK", expectedContentLength: 0, expectedVe
rsion: "1.0"); |
| 605 |
| 576 response = "HTTP/1.1 204 No Content\r\nContent-Length: 11\r\n\r\n"; | 606 response = "HTTP/1.1 204 No Content\r\nContent-Length: 11\r\n\r\n"; |
| 577 _testParseResponse(response, | 607 _testParseResponse(response, |
| 578 204, | 608 204, |
| 579 "No Content", | 609 "No Content", |
| 580 expectedContentLength: 11, | 610 expectedContentLength: 11, |
| 581 expectedBytesReceived: 0); | 611 expectedBytesReceived: 0); |
| 582 | 612 |
| 583 response = "HTTP/1.1 304 Not Modified\r\nContent-Length: 12\r\n\r\n"; | 613 response = "HTTP/1.1 304 Not Modified\r\nContent-Length: 12\r\n\r\n"; |
| 584 _testParseResponse(response, | 614 _testParseResponse(response, |
| 585 304, | 615 304, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 _testParseInvalidRequest(request); | 784 _testParseInvalidRequest(request); |
| 755 | 785 |
| 756 request = "GET / TTP/1.1\r\n\r\n"; | 786 request = "GET / TTP/1.1\r\n\r\n"; |
| 757 _testParseInvalidRequest(request); | 787 _testParseInvalidRequest(request); |
| 758 | 788 |
| 759 request = "GET / HTTP/1.\r\n\r\n"; | 789 request = "GET / HTTP/1.\r\n\r\n"; |
| 760 _testParseInvalidRequest(request); | 790 _testParseInvalidRequest(request); |
| 761 | 791 |
| 762 request = "GET / HTTP/1.1\r\nKeep-Alive: False\r\nbadheader\r\n\r\n"; | 792 request = "GET / HTTP/1.1\r\nKeep-Alive: False\r\nbadheader\r\n\r\n"; |
| 763 _testParseInvalidRequest(request); | 793 _testParseInvalidRequest(request); |
| 764 | |
| 765 // Currently no HTTP 1.0 support. | |
| 766 request = "GET / HTTP/1.0\r\n\r\n"; | |
| 767 _testParseInvalidRequest(request); | |
| 768 } | 794 } |
| 769 | 795 |
| 770 static void testParseInvalidResponse() { | 796 static void testParseInvalidResponse() { |
| 771 String response; | 797 String response; |
| 772 | 798 |
| 773 response = "HTTP/1.1\r\nContent-Length: 0\r\n\r\n"; | 799 response = "HTTP/1.1\r\nContent-Length: 0\r\n\r\n"; |
| 774 _testParseInvalidResponse(response); | 800 _testParseInvalidResponse(response); |
| 775 | 801 |
| 776 response = "HTTP/1.1 \r\nContent-Length: 0\r\n\r\n"; | 802 response = "HTTP/1.1 \r\nContent-Length: 0\r\n\r\n"; |
| 777 _testParseInvalidResponse(response); | 803 _testParseInvalidResponse(response); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 0123456789012345678901234567890\r | 842 0123456789012345678901234567890\r |
| 817 0\r\n\r\n"""; | 843 0\r\n\r\n"""; |
| 818 _testParseInvalidResponse(response); | 844 _testParseInvalidResponse(response); |
| 819 } | 845 } |
| 820 } | 846 } |
| 821 | 847 |
| 822 | 848 |
| 823 void main() { | 849 void main() { |
| 824 HttpParserTest.runAllTests(); | 850 HttpParserTest.runAllTests(); |
| 825 } | 851 } |
| OLD | NEW |