Chromium Code Reviews| 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 // Global constants. | 5 // Global constants. |
| 6 class _Const { | 6 class _Const { |
| 7 // Bytes for "HTTP/1.0". | 7 // Bytes for "HTTP/1.0". |
| 8 static final HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48]; | 8 static final HTTP10 = const [72, 84, 84, 80, 47, 49, 46, 48]; |
| 9 // Bytes for "HTTP/1.1". | 9 // Bytes for "HTTP/1.1". |
| 10 static final HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49]; | 10 static final HTTP11 = const [72, 84, 84, 80, 47, 49, 46, 49]; |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 681 _keepAlive = keepAlive; | 681 _keepAlive = keepAlive; |
| 682 } | 682 } |
| 683 | 683 |
| 684 int get statusCode() => _statusCode; | 684 int get statusCode() => _statusCode; |
| 685 void set statusCode(int statusCode) { | 685 void set statusCode(int statusCode) { |
| 686 if (_outputStream != null) return new HttpException("Header already sent"); | 686 if (_outputStream != null) return new HttpException("Header already sent"); |
| 687 _statusCode = statusCode; | 687 _statusCode = statusCode; |
| 688 } | 688 } |
| 689 | 689 |
| 690 String get reasonPhrase() => _findReasonPhrase(_statusCode); | 690 String get reasonPhrase() => _findReasonPhrase(_statusCode); |
| 691 void set reasonPhrase(String reasonPhrase) => _reasonPhrase = reasonPhrase; | 691 void set reasonPhrase(String reasonPhrase) { |
| 692 if (_outputStream != null) return new HttpException("Header already sent"); | |
| 693 _reasonPhrase = reasonPhrase; | |
| 694 } | |
| 692 | 695 |
| 693 // Set a header on the response. NOTE: If the same header is set | 696 // Set a header on the response. NOTE: If the same header is set |
| 694 // more than once only the last one will be part of the response. | 697 // more than once only the last one will be part of the response. |
| 695 void setHeader(String name, String value) { | 698 void setHeader(String name, String value) { |
| 696 if (_outputStream != null) return new HttpException("Header already sent"); | 699 if (_outputStream != null) return new HttpException("Header already sent"); |
| 697 _setHeader(name, value); | 700 _setHeader(name, value); |
| 698 } | 701 } |
| 699 | 702 |
| 700 OutputStream get outputStream() { | 703 OutputStream get outputStream() { |
| 701 if (_state == DONE) throw new HttpException("Response closed"); | 704 if (_state == DONE) throw new HttpException("Response closed"); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 718 // Delegate functions for the HttpOutputStream implementation. | 721 // Delegate functions for the HttpOutputStream implementation. |
| 719 bool _streamWrite(List<int> buffer, bool copyBuffer) { | 722 bool _streamWrite(List<int> buffer, bool copyBuffer) { |
| 720 return _write(buffer, copyBuffer); | 723 return _write(buffer, copyBuffer); |
| 721 } | 724 } |
| 722 | 725 |
| 723 bool _streamWriteFrom(List<int> buffer, int offset, int len) { | 726 bool _streamWriteFrom(List<int> buffer, int offset, int len) { |
| 724 return _writeList(buffer, offset, len); | 727 return _writeList(buffer, offset, len); |
| 725 } | 728 } |
| 726 | 729 |
| 727 void _streamClose() { | 730 void _streamClose() { |
| 731 _httpConnection._phase = _HttpConnectionBase.PHASE_IDLE; | |
| 728 _state = DONE; | 732 _state = DONE; |
| 729 // Stop tracking no pending write events. | 733 // Stop tracking no pending write events. |
| 730 _httpConnection.outputStream.onNoPendingWrites = null; | 734 _httpConnection.outputStream.onNoPendingWrites = null; |
| 731 // Ensure that any trailing data is written. | 735 // Ensure that any trailing data is written. |
| 732 _writeDone(); | 736 _writeDone(); |
| 733 // If the connection is closing then close the output stream to | 737 // If the connection is closing then close the output stream to |
| 734 // fully close the socket. | 738 // fully close the socket. |
| 735 if (_httpConnection._closing) { | 739 if (_httpConnection._closing) { |
| 736 _httpConnection.outputStream.close(); | 740 _httpConnection.outputStream.close(); |
| 737 } | 741 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 911 | 915 |
| 912 void set onError(void callback()) { | 916 void set onError(void callback()) { |
| 913 _requestOrResponse._streamSetErrorHandler(callback); | 917 _requestOrResponse._streamSetErrorHandler(callback); |
| 914 } | 918 } |
| 915 | 919 |
| 916 _HttpRequestResponseBase _requestOrResponse; | 920 _HttpRequestResponseBase _requestOrResponse; |
| 917 } | 921 } |
| 918 | 922 |
| 919 | 923 |
| 920 class _HttpConnectionBase { | 924 class _HttpConnectionBase { |
| 921 _HttpConnectionBase() : _sendBuffers = new Queue(), | 925 static final int PHASE_IDLE = 0; |
| 926 static final int PHASE_REQUEST = 1; | |
| 927 static final int PHASE_RESPONSE = 2; | |
| 928 | |
| 929 _HttpConnectionBase() : _phase = PHASE_IDLE, | |
| 930 _sendBuffers = new Queue(), | |
| 922 _httpParser = new HttpParser(); | 931 _httpParser = new HttpParser(); |
| 923 | 932 |
| 924 void _connectionEstablished(Socket socket) { | 933 void _connectionEstablished(Socket socket) { |
| 925 _socket = socket; | 934 _socket = socket; |
| 926 // Register handler for socket events. | 935 // Register handler for socket events. |
| 927 _socket.onData = _onData; | 936 _socket.onData = _onData; |
| 928 _socket.onClosed = _onClosed; | 937 _socket.onClosed = _onClosed; |
| 929 _socket.onError = _onError; | 938 _socket.onError = _onError; |
| 930 } | 939 } |
| 931 | 940 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 943 int bytesRead = _socket.readList(buffer, 0, available); | 952 int bytesRead = _socket.readList(buffer, 0, available); |
| 944 if (bytesRead > 0) { | 953 if (bytesRead > 0) { |
| 945 int parsed = _httpParser.writeList(buffer, 0, bytesRead); | 954 int parsed = _httpParser.writeList(buffer, 0, bytesRead); |
| 946 if (parsed != bytesRead) { | 955 if (parsed != bytesRead) { |
| 947 // TODO(sgjesse): Error handling. | 956 // TODO(sgjesse): Error handling. |
| 948 _socket.close(); | 957 _socket.close(); |
| 949 } | 958 } |
| 950 } | 959 } |
| 951 } | 960 } |
| 952 | 961 |
| 953 void _onClosed() { | 962 void _onClosed() { |
|
Anders Johnsen
2012/03/02 13:48:10
This is a lot easier to read. Thank you!
| |
| 954 // Client closed socket for writing. Socket should still be open | 963 if (_phase != PHASE_IDLE) { |
| 955 // for writing the response. | 964 // Client closed socket for writing. Socket should still be open |
| 956 _closing = true; | 965 // for writing the response. |
| 966 _closing = true; | |
| 967 } else { | |
| 968 // The connection is currently not used by any request just close it. | |
| 969 _socket.close(); | |
| 970 } | |
| 957 if (_onDisconnectCallback != null) _onDisconnectCallback(); | 971 if (_onDisconnectCallback != null) _onDisconnectCallback(); |
| 958 } | 972 } |
| 959 | 973 |
| 960 void _onError() { | 974 void _onError() { |
| 961 // If an error occours, treat the socket as closed. | 975 // If an error occours, treat the socket as closed. |
| 962 _onClosed(); | 976 _onClosed(); |
| 963 if (_onErrorCallback != null) { | 977 if (_onErrorCallback != null) { |
| 964 _onErrorCallback("Connection closed while sending data to client."); | 978 _onErrorCallback("Connection closed while sending data to client."); |
| 965 } | 979 } |
| 966 } | 980 } |
| 967 | 981 |
| 968 void set onDisconnect(void callback()) { | 982 void set onDisconnect(void callback()) { |
| 969 _onDisconnectCallback = callback; | 983 _onDisconnectCallback = callback; |
| 970 } | 984 } |
| 971 | 985 |
| 972 void set onError(void callback(String errorMessage)) { | 986 void set onError(void callback(String errorMessage)) { |
| 973 _onErrorCallback = callback; | 987 _onErrorCallback = callback; |
| 974 } | 988 } |
| 975 | 989 |
| 990 int _phase; | |
| 976 Socket _socket; | 991 Socket _socket; |
| 977 bool _closing = false; // Is the socket closed by the client? | 992 bool _closing = false; // Is the socket closed by the client? |
| 978 HttpParser _httpParser; | 993 HttpParser _httpParser; |
| 979 | 994 |
| 980 Queue _sendBuffers; | 995 Queue _sendBuffers; |
| 981 | 996 |
| 982 Function _onDisconnectCallback; | 997 Function _onDisconnectCallback; |
| 983 Function _onErrorCallback; | 998 Function _onErrorCallback; |
| 984 } | 999 } |
| 985 | 1000 |
| 986 | 1001 |
| 987 // HTTP server connection over a socket. | 1002 // HTTP server connection over a socket. |
| 988 class _HttpConnection extends _HttpConnectionBase { | 1003 class _HttpConnection extends _HttpConnectionBase { |
| 989 _HttpConnection() { | 1004 _HttpConnection() { |
| 990 // Register HTTP parser callbacks. | 1005 // Register HTTP parser callbacks. |
| 991 _httpParser.requestStart = | 1006 _httpParser.requestStart = |
| 992 (method, uri) => _onRequestStart(method, uri); | 1007 (method, uri) => _onRequestStart(method, uri); |
| 993 _httpParser.responseStart = | 1008 _httpParser.responseStart = |
| 994 (statusCode, reasonPhrase) => | 1009 (statusCode, reasonPhrase) => |
| 995 _onResponseStart(statusCode, reasonPhrase); | 1010 _onResponseStart(statusCode, reasonPhrase); |
| 996 _httpParser.headerReceived = | 1011 _httpParser.headerReceived = |
| 997 (name, value) => _onHeaderReceived(name, value); | 1012 (name, value) => _onHeaderReceived(name, value); |
| 998 _httpParser.headersComplete = () => _onHeadersComplete(); | 1013 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 999 _httpParser.dataReceived = (data) => _onDataReceived(data); | 1014 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 1000 _httpParser.dataEnd = () => _onDataEnd(); | 1015 _httpParser.dataEnd = () => _onDataEnd(); |
| 1001 } | 1016 } |
| 1002 | 1017 |
| 1003 void _onRequestStart(String method, String uri) { | 1018 void _onRequestStart(String method, String uri) { |
| 1004 // Create new request and response objects for this request. | 1019 // Create new request and response objects for this request. |
| 1020 _phase = PHASE_REQUEST; | |
| 1005 _request = new _HttpRequest(this); | 1021 _request = new _HttpRequest(this); |
| 1006 _response = new _HttpResponse(this); | 1022 _response = new _HttpResponse(this); |
| 1007 _request._onRequestStart(method, uri); | 1023 _request._onRequestStart(method, uri); |
| 1008 } | 1024 } |
| 1009 | 1025 |
| 1010 void _onResponseStart(int statusCode, String reasonPhrase) { | 1026 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 1011 // TODO(sgjesse): Error handling. | 1027 // TODO(sgjesse): Error handling. |
| 1012 } | 1028 } |
| 1013 | 1029 |
| 1014 void _onHeaderReceived(String name, String value) { | 1030 void _onHeaderReceived(String name, String value) { |
| 1015 _request._onHeaderReceived(name, value); | 1031 _request._onHeaderReceived(name, value); |
| 1016 } | 1032 } |
| 1017 | 1033 |
| 1018 void _onHeadersComplete() { | 1034 void _onHeadersComplete() { |
| 1019 _request._onHeadersComplete(); | 1035 _request._onHeadersComplete(); |
| 1020 _response.keepAlive = _httpParser.keepAlive; | 1036 _response.keepAlive = _httpParser.keepAlive; |
| 1021 if (requestReceived != null) { | 1037 if (requestReceived != null) { |
| 1022 requestReceived(_request, _response); | 1038 requestReceived(_request, _response); |
| 1023 } | 1039 } |
| 1024 } | 1040 } |
| 1025 | 1041 |
| 1026 void _onDataReceived(List<int> data) { | 1042 void _onDataReceived(List<int> data) { |
| 1027 _request._onDataReceived(data); | 1043 _request._onDataReceived(data); |
| 1028 } | 1044 } |
| 1029 | 1045 |
| 1030 void _onDataEnd() { | 1046 void _onDataEnd() { |
| 1047 // Phase might already have gone to PHASE_IDLE if the response is | |
| 1048 // sent without waiting for request body. | |
| 1049 if (_phase == PHASE_REQUEST) { | |
| 1050 _phase = PHASE_RESPONSE; | |
| 1051 } | |
| 1031 _request._onDataEnd(); | 1052 _request._onDataEnd(); |
| 1032 } | 1053 } |
| 1033 | 1054 |
| 1034 HttpRequest _request; | 1055 HttpRequest _request; |
| 1035 HttpResponse _response; | 1056 HttpResponse _response; |
| 1036 | 1057 |
| 1037 // Callbacks. | 1058 // Callbacks. |
| 1038 var requestReceived; | 1059 var requestReceived; |
| 1039 } | 1060 } |
| 1040 | 1061 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1058 } | 1079 } |
| 1059 } | 1080 } |
| 1060 } | 1081 } |
| 1061 connection.onDisconnect = onDisconnect; | 1082 connection.onDisconnect = onDisconnect; |
| 1062 void onError(String errorMessage) { | 1083 void onError(String errorMessage) { |
| 1063 if (_onError != null) _onError(errorMessage); | 1084 if (_onError != null) _onError(errorMessage); |
| 1064 } | 1085 } |
| 1065 connection.onError = onError; | 1086 connection.onError = onError; |
| 1066 } | 1087 } |
| 1067 | 1088 |
| 1068 // TODO(ajohnsen): Use Set once Socket is Hashable. | 1089 // TODO(ajohnsen): Use Set once Socket is Hashable. |
|
Anders Johnsen
2012/03/02 13:48:10
Now that Socket is hashable, could you use a Set h
Søren Gjesse
2012/03/05 07:03:41
Done.
| |
| 1069 _connections = new List<_HttpConnection>(); | 1090 _connections = new List<_HttpConnection>(); |
| 1070 _server = new ServerSocket(host, port, backlog); | 1091 _server = new ServerSocket(host, port, backlog); |
| 1071 _server.onConnection = onConnection; | 1092 _server.onConnection = onConnection; |
| 1072 } | 1093 } |
| 1073 | 1094 |
| 1074 void close() => _server.close(); | 1095 void close() => _server.close(); |
| 1075 int get port() => _server.port; | 1096 int get port() => _server.port; |
| 1076 | 1097 |
| 1077 void set onError(void handler(String errorMessage)) { | 1098 void set onError(void handler(String errorMessage)) { |
| 1078 _onError = handler; | 1099 _onError = handler; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1365 | 1386 |
| 1366 void _markReturned() { | 1387 void _markReturned() { |
| 1367 _socket.onData = null; | 1388 _socket.onData = null; |
| 1368 _socket.onClosed = null; | 1389 _socket.onClosed = null; |
| 1369 _socket.onError = null; | 1390 _socket.onError = null; |
| 1370 _returnTime = new Date.now(); | 1391 _returnTime = new Date.now(); |
| 1371 } | 1392 } |
| 1372 | 1393 |
| 1373 Duration _idleTime(Date now) => now.difference(_returnTime); | 1394 Duration _idleTime(Date now) => now.difference(_returnTime); |
| 1374 | 1395 |
| 1396 int hashCode() => _socket.hashCode(); | |
| 1397 | |
| 1375 String _host; | 1398 String _host; |
| 1376 int _port; | 1399 int _port; |
| 1377 Socket _socket; | 1400 Socket _socket; |
| 1378 Date _returnTime; | 1401 Date _returnTime; |
| 1379 } | 1402 } |
| 1380 | 1403 |
| 1381 | 1404 |
| 1382 class _HttpClient implements HttpClient { | 1405 class _HttpClient implements HttpClient { |
| 1383 static final int DEFAULT_EVICTION_TIMEOUT = 60000; | 1406 static final int DEFAULT_EVICTION_TIMEOUT = 60000; |
| 1384 | 1407 |
| 1385 _HttpClient() : _openSockets = new Map(), _shutdown = false; | 1408 _HttpClient() : _openSockets = new Map(), |
| 1409 _activeSockets = new Set(), | |
| 1410 _shutdown = false; | |
| 1386 | 1411 |
| 1387 HttpClientConnection open( | 1412 HttpClientConnection open( |
| 1388 String method, String host, int port, String path) { | 1413 String method, String host, int port, String path) { |
| 1389 if (_shutdown) throw new HttpException("HttpClient shutdown"); | 1414 if (_shutdown) throw new HttpException("HttpClient shutdown"); |
| 1390 return _prepareHttpClientConnection(host, port, method, path); | 1415 return _prepareHttpClientConnection(host, port, method, path); |
| 1391 } | 1416 } |
| 1392 | 1417 |
| 1393 HttpClientConnection get(String host, int port, String path) { | 1418 HttpClientConnection get(String host, int port, String path) { |
| 1394 return open("GET", host, port, path); | 1419 return open("GET", host, port, path); |
| 1395 } | 1420 } |
| 1396 | 1421 |
| 1397 HttpClientConnection post(String host, int port, String path) { | 1422 HttpClientConnection post(String host, int port, String path) { |
| 1398 return open("POST", host, port, path); | 1423 return open("POST", host, port, path); |
| 1399 } | 1424 } |
| 1400 | 1425 |
| 1401 void shutdown() { | 1426 void shutdown() { |
| 1402 _openSockets.forEach( | 1427 _openSockets.forEach((String key, Queue<_SocketConnection> connections) { |
| 1403 void _(String key, Queue<_SocketConnection> connections) { | 1428 while (!connections.isEmpty()) { |
| 1404 while (!connections.isEmpty()) { | 1429 _SocketConnection socketConn = connections.removeFirst(); |
| 1405 var socketConn = connections.removeFirst(); | 1430 socketConn._socket.close(); |
| 1406 socketConn._socket.close(); | 1431 } |
| 1407 } | 1432 }); |
| 1408 }); | 1433 _activeSockets.forEach((_SocketConnection socketConn) { |
| 1434 socketConn._socket.close(); | |
| 1435 }); | |
| 1409 if (_evictionTimer != null) { | 1436 if (_evictionTimer != null) { |
| 1410 _evictionTimer.cancel(); | 1437 _evictionTimer.cancel(); |
| 1411 } | 1438 } |
| 1412 _shutdown = true; | 1439 _shutdown = true; |
| 1413 } | 1440 } |
| 1414 | 1441 |
| 1415 String _connectionKey(String host, int port) { | 1442 String _connectionKey(String host, int port) { |
| 1416 return "$host:$port"; | 1443 return "$host:$port"; |
| 1417 } | 1444 } |
| 1418 | 1445 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1434 | 1461 |
| 1435 // If there are active connections for this key get the first one | 1462 // If there are active connections for this key get the first one |
| 1436 // otherwise create a new one. | 1463 // otherwise create a new one. |
| 1437 Queue socketConnections = _openSockets[_connectionKey(host, port)]; | 1464 Queue socketConnections = _openSockets[_connectionKey(host, port)]; |
| 1438 if (socketConnections == null || socketConnections.isEmpty()) { | 1465 if (socketConnections == null || socketConnections.isEmpty()) { |
| 1439 Socket socket = new Socket(host, port); | 1466 Socket socket = new Socket(host, port); |
| 1440 socket.onConnect = () { | 1467 socket.onConnect = () { |
| 1441 socket.onError = null; | 1468 socket.onError = null; |
| 1442 _SocketConnection socketConn = | 1469 _SocketConnection socketConn = |
| 1443 new _SocketConnection(host, port, socket); | 1470 new _SocketConnection(host, port, socket); |
| 1471 _activeSockets.add(socketConn); | |
| 1444 _connectionOpened(socketConn, connection); | 1472 _connectionOpened(socketConn, connection); |
| 1445 }; | 1473 }; |
| 1446 socket.onError = () { | 1474 socket.onError = () { |
| 1447 if (_onError !== null) { | 1475 if (_onError !== null) { |
| 1448 _onError(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR); | 1476 _onError(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR); |
| 1449 } | 1477 } |
| 1450 }; | 1478 }; |
| 1451 } else { | 1479 } else { |
| 1452 _SocketConnection socketConn = socketConnections.removeFirst(); | 1480 _SocketConnection socketConn = socketConnections.removeFirst(); |
| 1481 _activeSockets.add(socketConn); | |
| 1453 new Timer((ignored) => _connectionOpened(socketConn, connection), 0); | 1482 new Timer((ignored) => _connectionOpened(socketConn, connection), 0); |
| 1454 | 1483 |
| 1455 // Get rid of eviction timer if there are no more active connections. | 1484 // Get rid of eviction timer if there are no more active connections. |
| 1456 if (socketConnections.isEmpty()) { | 1485 if (socketConnections.isEmpty()) { |
| 1457 _evictionTimer.cancel(); | 1486 _evictionTimer.cancel(); |
| 1458 _evictionTimer = null; | 1487 _evictionTimer = null; |
| 1459 } | 1488 } |
| 1460 } | 1489 } |
| 1461 | 1490 |
| 1462 return connection; | 1491 return connection; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1494 } else { | 1523 } else { |
| 1495 break; | 1524 break; |
| 1496 } | 1525 } |
| 1497 } | 1526 } |
| 1498 }); | 1527 }); |
| 1499 } | 1528 } |
| 1500 _evictionTimer = new Timer.repeating(_handleEviction, 10000); | 1529 _evictionTimer = new Timer.repeating(_handleEviction, 10000); |
| 1501 } | 1530 } |
| 1502 | 1531 |
| 1503 // Return connection. | 1532 // Return connection. |
| 1533 _activeSockets.remove(socketConn); | |
| 1504 sockets.addFirst(socketConn); | 1534 sockets.addFirst(socketConn); |
| 1505 socketConn._markReturned(); | 1535 socketConn._markReturned(); |
| 1506 } | 1536 } |
| 1507 | 1537 |
| 1508 void set onError(void callback(int status)) { | 1538 void set onError(void callback(int status)) { |
| 1509 _onError = callback; | 1539 _onError = callback; |
| 1510 } | 1540 } |
| 1511 | 1541 |
| 1512 Function _onOpen; | 1542 Function _onOpen; |
| 1513 Function _onError; | 1543 Function _onError; |
| 1514 Map<String, Queue<_SocketConnection>> _openSockets; | 1544 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1545 Set<_SocketConnection> _activeSockets; | |
| 1515 Timer _evictionTimer; | 1546 Timer _evictionTimer; |
| 1516 bool _shutdown; // Has this HTTP client been shutdown? | 1547 bool _shutdown; // Has this HTTP client been shutdown? |
| 1517 } | 1548 } |
| 1518 | 1549 |
| 1519 | 1550 |
| 1520 class HttpUtil { | 1551 class HttpUtil { |
| 1521 static String decodeUrlEncodedString(String urlEncoded) { | 1552 static String decodeUrlEncodedString(String urlEncoded) { |
| 1522 void invalidEscape() { | 1553 void invalidEscape() { |
| 1523 // TODO(sgjesse): Handle the error. | 1554 // TODO(sgjesse): Handle the error. |
| 1524 } | 1555 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1568 } else { | 1599 } else { |
| 1569 value = queryString.substring(currentPosition, position); | 1600 value = queryString.substring(currentPosition, position); |
| 1570 currentPosition = position + 1; | 1601 currentPosition = position + 1; |
| 1571 } | 1602 } |
| 1572 result[HttpUtil.decodeUrlEncodedString(name)] = | 1603 result[HttpUtil.decodeUrlEncodedString(name)] = |
| 1573 HttpUtil.decodeUrlEncodedString(value); | 1604 HttpUtil.decodeUrlEncodedString(value); |
| 1574 } | 1605 } |
| 1575 return result; | 1606 return result; |
| 1576 } | 1607 } |
| 1577 } | 1608 } |
| OLD | NEW |