| 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 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 String get queryString() => _queryString; | 590 String get queryString() => _queryString; |
| 591 Map get queryParameters() => _queryParameters; | 591 Map get queryParameters() => _queryParameters; |
| 592 | 592 |
| 593 InputStream get inputStream() { | 593 InputStream get inputStream() { |
| 594 if (_inputStream == null) { | 594 if (_inputStream == null) { |
| 595 _inputStream = new _HttpInputStream(this); | 595 _inputStream = new _HttpInputStream(this); |
| 596 } | 596 } |
| 597 return _inputStream; | 597 return _inputStream; |
| 598 } | 598 } |
| 599 | 599 |
| 600 void _requestStartHandler(String method, String uri) { | 600 void _onRequestStart(String method, String uri) { |
| 601 _method = method; | 601 _method = method; |
| 602 _uri = uri; | 602 _uri = uri; |
| 603 _parseRequestUri(uri); | 603 _parseRequestUri(uri); |
| 604 } | 604 } |
| 605 | 605 |
| 606 void _headerReceivedHandler(String name, String value) { | 606 void _onHeaderReceived(String name, String value) { |
| 607 _setHeader(name, value); | 607 _setHeader(name, value); |
| 608 } | 608 } |
| 609 | 609 |
| 610 void _headersCompleteHandler() { | 610 void _onHeadersComplete() { |
| 611 // Prepare for receiving data. | 611 // Prepare for receiving data. |
| 612 _buffer = new _BufferList(); | 612 _buffer = new _BufferList(); |
| 613 } | 613 } |
| 614 | 614 |
| 615 void _dataReceivedHandler(List<int> data) { | 615 void _onDataReceived(List<int> data) { |
| 616 _buffer.add(data); | 616 _buffer.add(data); |
| 617 if (_inputStream != null) _inputStream._dataReceived(); | 617 if (_inputStream != null) _inputStream._dataReceived(); |
| 618 } | 618 } |
| 619 | 619 |
| 620 void _dataEndHandler() { | 620 void _onDataEnd() { |
| 621 if (_inputStream != null) _inputStream._closeReceived(); | 621 if (_inputStream != null) _inputStream._closeReceived(); |
| 622 } | 622 } |
| 623 | 623 |
| 624 // Escaped characters in uri are expected to have been parsed. | 624 // Escaped characters in uri are expected to have been parsed. |
| 625 void _parseRequestUri(String uri) { | 625 void _parseRequestUri(String uri) { |
| 626 int position; | 626 int position; |
| 627 position = uri.indexOf("?", 0); | 627 position = uri.indexOf("?", 0); |
| 628 if (position == -1) { | 628 if (position == -1) { |
| 629 _path = HttpUtil.decodeUrlEncodedString(_uri); | 629 _path = HttpUtil.decodeUrlEncodedString(_uri); |
| 630 _queryString = null; | 630 _queryString = null; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 return _write(buffer, copyBuffer); | 710 return _write(buffer, copyBuffer); |
| 711 } | 711 } |
| 712 | 712 |
| 713 bool _streamWriteFrom(List<int> buffer, int offset, int len) { | 713 bool _streamWriteFrom(List<int> buffer, int offset, int len) { |
| 714 return _writeList(buffer, offset, len); | 714 return _writeList(buffer, offset, len); |
| 715 } | 715 } |
| 716 | 716 |
| 717 void _streamClose() { | 717 void _streamClose() { |
| 718 _state = DONE; | 718 _state = DONE; |
| 719 // Stop tracking no pending write events. | 719 // Stop tracking no pending write events. |
| 720 _httpConnection.outputStream.noPendingWriteHandler = null; | 720 _httpConnection.outputStream.onNoPendingWrite = null; |
| 721 // Ensure that any trailing data is written. | 721 // Ensure that any trailing data is written. |
| 722 _writeDone(); | 722 _writeDone(); |
| 723 // If the connection is closing then close the output stream to | 723 // If the connection is closing then close the output stream to |
| 724 // fully close the socket. | 724 // fully close the socket. |
| 725 if (_httpConnection._closing) { | 725 if (_httpConnection._closing) { |
| 726 _httpConnection.outputStream.close(); | 726 _httpConnection.outputStream.close(); |
| 727 } | 727 } |
| 728 } | 728 } |
| 729 | 729 |
| 730 void _streamSetNoPendingWriteHandler(callback()) { | 730 void _streamSetNoPendingWriteHandler(callback()) { |
| 731 if (_state != DONE) { | 731 if (_state != DONE) { |
| 732 _httpConnection.outputStream.noPendingWriteHandler = callback; | 732 _httpConnection.outputStream.onNoPendingWrite = callback; |
| 733 } | 733 } |
| 734 } | 734 } |
| 735 | 735 |
| 736 void _streamSetCloseHandler(callback()) { | 736 void _streamSetCloseHandler(callback()) { |
| 737 // TODO(sgjesse): Handle this. | 737 // TODO(sgjesse): Handle this. |
| 738 } | 738 } |
| 739 | 739 |
| 740 void _streamSetErrorHandler(callback()) { | 740 void _streamSetErrorHandler(callback()) { |
| 741 // TODO(sgjesse): Handle this. | 741 // TODO(sgjesse): Handle this. |
| 742 } | 742 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 } | 884 } |
| 885 | 885 |
| 886 void close() { | 886 void close() { |
| 887 _requestOrResponse._streamClose(); | 887 _requestOrResponse._streamClose(); |
| 888 } | 888 } |
| 889 | 889 |
| 890 void destroy() { | 890 void destroy() { |
| 891 throw "Not implemented"; | 891 throw "Not implemented"; |
| 892 } | 892 } |
| 893 | 893 |
| 894 void set noPendingWriteHandler(void callback()) { | 894 void set onNoPendingWrite(void callback()) { |
| 895 _requestOrResponse._streamSetNoPendingWriteHandler(callback); | 895 _requestOrResponse._streamSetNoPendingWriteHandler(callback); |
| 896 } | 896 } |
| 897 | 897 |
| 898 void set closeHandler(void callback()) { | 898 void set onClose(void callback()) { |
| 899 _requestOrResponse._streamSetCloseHandler(callback); | 899 _requestOrResponse._streamSetCloseHandler(callback); |
| 900 } | 900 } |
| 901 | 901 |
| 902 void set errorHandler(void callback()) { | 902 void set onError(void callback()) { |
| 903 _requestOrResponse._streamSetErrorHandler(callback); | 903 _requestOrResponse._streamSetErrorHandler(callback); |
| 904 } | 904 } |
| 905 | 905 |
| 906 _HttpRequestResponseBase _requestOrResponse; | 906 _HttpRequestResponseBase _requestOrResponse; |
| 907 } | 907 } |
| 908 | 908 |
| 909 | 909 |
| 910 class _HttpConnectionBase { | 910 class _HttpConnectionBase { |
| 911 _HttpConnectionBase() : _sendBuffers = new Queue(), | 911 _HttpConnectionBase() : _sendBuffers = new Queue(), |
| 912 _httpParser = new HttpParser(); | 912 _httpParser = new HttpParser(); |
| 913 | 913 |
| 914 void _connectionEstablished(Socket socket) { | 914 void _connectionEstablished(Socket socket) { |
| 915 _socket = socket; | 915 _socket = socket; |
| 916 // Register handler for socket events. | 916 // Register handler for socket events. |
| 917 _socket.dataHandler = _dataHandler; | 917 _socket.onData = _onData; |
| 918 _socket.closeHandler = _closeHandler; | 918 _socket.onClose = _onClose; |
| 919 _socket.errorHandler = _errorHandler; | 919 _socket.onError = _onError; |
| 920 } | 920 } |
| 921 | 921 |
| 922 OutputStream get outputStream() { | 922 OutputStream get outputStream() { |
| 923 return _socket.outputStream; | 923 return _socket.outputStream; |
| 924 } | 924 } |
| 925 | 925 |
| 926 void _dataHandler() { | 926 void _onData() { |
| 927 int available = _socket.available(); | 927 int available = _socket.available(); |
| 928 if (available == 0) { | 928 if (available == 0) { |
| 929 return; | 929 return; |
| 930 } | 930 } |
| 931 | 931 |
| 932 ByteArray buffer = new ByteArray(available); | 932 ByteArray buffer = new ByteArray(available); |
| 933 int bytesRead = _socket.readList(buffer, 0, available); | 933 int bytesRead = _socket.readList(buffer, 0, available); |
| 934 if (bytesRead > 0) { | 934 if (bytesRead > 0) { |
| 935 int parsed = _httpParser.writeList(buffer, 0, bytesRead); | 935 int parsed = _httpParser.writeList(buffer, 0, bytesRead); |
| 936 if (parsed != bytesRead) { | 936 if (parsed != bytesRead) { |
| 937 // TODO(sgjesse): Error handling. | 937 // TODO(sgjesse): Error handling. |
| 938 _socket.close(); | 938 _socket.close(); |
| 939 } | 939 } |
| 940 } | 940 } |
| 941 } | 941 } |
| 942 | 942 |
| 943 void _closeHandler() { | 943 void _onClose() { |
| 944 // Client closed socket for writing. Socket should still be open | 944 // Client closed socket for writing. Socket should still be open |
| 945 // for writing the response. | 945 // for writing the response. |
| 946 _closing = true; | 946 _closing = true; |
| 947 if (_disconnectHandlerCallback != null) _disconnectHandlerCallback(); | 947 if (_onDisconnectCallback != null) _onDisconnectCallback(); |
| 948 } | 948 } |
| 949 | 949 |
| 950 void _errorHandler() { | 950 void _onError() { |
| 951 // If an error occours, treat the socket as closed. | 951 // If an error occours, treat the socket as closed. |
| 952 _closeHandler(); | 952 _onClose(); |
| 953 if (_errorHandlerCallback != null) { | 953 if (_onErrorCallback != null) { |
| 954 _errorHandlerCallback("Connection closed while sending data to client."); | 954 _onErrorCallback("Connection closed while sending data to client."); |
| 955 } | 955 } |
| 956 } | 956 } |
| 957 | 957 |
| 958 void set disconnectHandler(void callback()) { | 958 void set onDisconnect(void callback()) { |
| 959 _disconnectHandlerCallback = callback; | 959 _onDisconnectCallback = callback; |
| 960 } | 960 } |
| 961 | 961 |
| 962 void set errorHandler(void callback(String errorMessage)) { | 962 void set onError(void callback(String errorMessage)) { |
| 963 _errorHandlerCallback = callback; | 963 _onErrorCallback = callback; |
| 964 } | 964 } |
| 965 | 965 |
| 966 Socket _socket; | 966 Socket _socket; |
| 967 bool _closing = false; // Is the socket closed by the client? | 967 bool _closing = false; // Is the socket closed by the client? |
| 968 HttpParser _httpParser; | 968 HttpParser _httpParser; |
| 969 | 969 |
| 970 Queue _sendBuffers; | 970 Queue _sendBuffers; |
| 971 | 971 |
| 972 Function _disconnectHandlerCallback; | 972 Function _onDisconnectCallback; |
| 973 Function _errorHandlerCallback; | 973 Function _onErrorCallback; |
| 974 } | 974 } |
| 975 | 975 |
| 976 | 976 |
| 977 // HTTP server connection over a socket. | 977 // HTTP server connection over a socket. |
| 978 class _HttpConnection extends _HttpConnectionBase { | 978 class _HttpConnection extends _HttpConnectionBase { |
| 979 _HttpConnection() { | 979 _HttpConnection() { |
| 980 // Register HTTP parser callbacks. | 980 // Register HTTP parser callbacks. |
| 981 _httpParser.requestStart = | 981 _httpParser.requestStart = |
| 982 (method, uri) => _requestStartHandler(method, uri); | 982 (method, uri) => _onRequestStart(method, uri); |
| 983 _httpParser.responseStart = | 983 _httpParser.responseStart = |
| 984 (statusCode, reasonPhrase) => | 984 (statusCode, reasonPhrase) => |
| 985 _responseStartHandler(statusCode, reasonPhrase); | 985 _onResponseStart(statusCode, reasonPhrase); |
| 986 _httpParser.headerReceived = | 986 _httpParser.headerReceived = |
| 987 (name, value) => _headerReceivedHandler(name, value); | 987 (name, value) => _onHeaderReceived(name, value); |
| 988 _httpParser.headersComplete = () => _headersCompleteHandler(); | 988 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 989 _httpParser.dataReceived = (data) => _dataReceivedHandler(data); | 989 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 990 _httpParser.dataEnd = () => _dataEndHandler(); | 990 _httpParser.dataEnd = () => _onDataEnd(); |
| 991 } | 991 } |
| 992 | 992 |
| 993 void _requestStartHandler(String method, String uri) { | 993 void _onRequestStart(String method, String uri) { |
| 994 // Create new request and response objects for this request. | 994 // Create new request and response objects for this request. |
| 995 _request = new _HttpRequest(this); | 995 _request = new _HttpRequest(this); |
| 996 _response = new _HttpResponse(this); | 996 _response = new _HttpResponse(this); |
| 997 _request._requestStartHandler(method, uri); | 997 _request._onRequestStart(method, uri); |
| 998 } | 998 } |
| 999 | 999 |
| 1000 void _responseStartHandler(int statusCode, String reasonPhrase) { | 1000 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 1001 // TODO(sgjesse): Error handling. | 1001 // TODO(sgjesse): Error handling. |
| 1002 } | 1002 } |
| 1003 | 1003 |
| 1004 void _headerReceivedHandler(String name, String value) { | 1004 void _onHeaderReceived(String name, String value) { |
| 1005 _request._headerReceivedHandler(name, value); | 1005 _request._onHeaderReceived(name, value); |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 void _headersCompleteHandler() { | 1008 void _onHeadersComplete() { |
| 1009 _request._headersCompleteHandler(); | 1009 _request._onHeadersComplete(); |
| 1010 _response.keepAlive = _httpParser.keepAlive; | 1010 _response.keepAlive = _httpParser.keepAlive; |
| 1011 if (requestReceived != null) { | 1011 if (requestReceived != null) { |
| 1012 requestReceived(_request, _response); | 1012 requestReceived(_request, _response); |
| 1013 } | 1013 } |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 void _dataReceivedHandler(List<int> data) { | 1016 void _onDataReceived(List<int> data) { |
| 1017 _request._dataReceivedHandler(data); | 1017 _request._onDataReceived(data); |
| 1018 } | 1018 } |
| 1019 | 1019 |
| 1020 void _dataEndHandler() { | 1020 void _onDataEnd() { |
| 1021 _request._dataEndHandler(); | 1021 _request._onDataEnd(); |
| 1022 } | 1022 } |
| 1023 | 1023 |
| 1024 HttpRequest _request; | 1024 HttpRequest _request; |
| 1025 HttpResponse _response; | 1025 HttpResponse _response; |
| 1026 | 1026 |
| 1027 // Callbacks. | 1027 // Callbacks. |
| 1028 var requestReceived; | 1028 var requestReceived; |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 | 1031 |
| 1032 // HTTP server waiting for socket connections. The connections are | 1032 // HTTP server waiting for socket connections. The connections are |
| 1033 // managed by the server and as requests are received the request. | 1033 // managed by the server and as requests are received the request. |
| 1034 class _HttpServer implements HttpServer { | 1034 class _HttpServer implements HttpServer { |
| 1035 void listen(String host, int port, [int backlog = 5]) { | 1035 void listen(String host, int port, [int backlog = 5]) { |
| 1036 | 1036 |
| 1037 void connectionHandler(Socket socket) { | 1037 void onConnection(Socket socket) { |
| 1038 // Accept the client connection. | 1038 // Accept the client connection. |
| 1039 _HttpConnection connection = new _HttpConnection(); | 1039 _HttpConnection connection = new _HttpConnection(); |
| 1040 connection._connectionEstablished(socket); | 1040 connection._connectionEstablished(socket); |
| 1041 connection.requestReceived = _requestHandler; | 1041 connection.requestReceived = _onRequest; |
| 1042 _connections.add(connection); | 1042 _connections.add(connection); |
| 1043 void disconnectHandler() { | 1043 void onDisconnect() { |
| 1044 for (int i = 0; i < _connections.length; i++) { | 1044 for (int i = 0; i < _connections.length; i++) { |
| 1045 if (_connections[i] == connection) { | 1045 if (_connections[i] == connection) { |
| 1046 _connections.removeRange(i, 1); | 1046 _connections.removeRange(i, 1); |
| 1047 break; | 1047 break; |
| 1048 } | 1048 } |
| 1049 } | 1049 } |
| 1050 } | 1050 } |
| 1051 connection.disconnectHandler = disconnectHandler; | 1051 connection.onDisconnect = onDisconnect; |
| 1052 void errorHandler(String errorMessage) { | 1052 void onError(String errorMessage) { |
| 1053 if (_errorHandler != null) _errorHandler(errorMessage); | 1053 if (_onError != null) _onError(errorMessage); |
| 1054 } | 1054 } |
| 1055 connection.errorHandler = errorHandler; | 1055 connection.onError = onError; |
| 1056 } | 1056 } |
| 1057 | 1057 |
| 1058 // TODO(ajohnsen): Use Set once Socket is Hashable. | 1058 // TODO(ajohnsen): Use Set once Socket is Hashable. |
| 1059 _connections = new List<_HttpConnection>(); | 1059 _connections = new List<_HttpConnection>(); |
| 1060 _server = new ServerSocket(host, port, backlog); | 1060 _server = new ServerSocket(host, port, backlog); |
| 1061 _server.connectionHandler = connectionHandler; | 1061 _server.onConnection = onConnection; |
| 1062 } | 1062 } |
| 1063 | 1063 |
| 1064 void close() => _server.close(); | 1064 void close() => _server.close(); |
| 1065 int get port() => _server.port; | 1065 int get port() => _server.port; |
| 1066 | 1066 |
| 1067 void set errorHandler(void handler(String errorMessage)) { | 1067 void set onError(void handler(String errorMessage)) { |
| 1068 _errorHandler = handler; | 1068 _onError = handler; |
| 1069 } | 1069 } |
| 1070 | 1070 |
| 1071 void set requestHandler(void handler(HttpRequest, HttpResponse)) { | 1071 void set onRequest(void handler(HttpRequest, HttpResponse)) { |
| 1072 _requestHandler = handler; | 1072 _onRequest = handler; |
| 1073 } | 1073 } |
| 1074 | 1074 |
| 1075 ServerSocket _server; // The server listen socket. | 1075 ServerSocket _server; // The server listen socket. |
| 1076 List<_HttpConnection> _connections; // List of currently connected clients. | 1076 List<_HttpConnection> _connections; // List of currently connected clients. |
| 1077 Function _requestHandler; | 1077 Function _onRequest; |
| 1078 Function _errorHandler; | 1078 Function _onError; |
| 1079 } | 1079 } |
| 1080 | 1080 |
| 1081 | 1081 |
| 1082 class _HttpClientRequest | 1082 class _HttpClientRequest |
| 1083 extends _HttpRequestResponseBase implements HttpClientRequest { | 1083 extends _HttpRequestResponseBase implements HttpClientRequest { |
| 1084 static final int START = 0; | 1084 static final int START = 0; |
| 1085 static final int HEADERS_SENT = 1; | 1085 static final int HEADERS_SENT = 1; |
| 1086 static final int DONE = 2; | 1086 static final int DONE = 2; |
| 1087 | 1087 |
| 1088 _HttpClientRequest(String this._method, | 1088 _HttpClientRequest(String this._method, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 return _write(buffer, copyBuffer); | 1128 return _write(buffer, copyBuffer); |
| 1129 } | 1129 } |
| 1130 | 1130 |
| 1131 bool _streamWriteFrom(List<int> buffer, int offset, int len) { | 1131 bool _streamWriteFrom(List<int> buffer, int offset, int len) { |
| 1132 return _writeList(buffer, offset, len); | 1132 return _writeList(buffer, offset, len); |
| 1133 } | 1133 } |
| 1134 | 1134 |
| 1135 void _streamClose() { | 1135 void _streamClose() { |
| 1136 _state = DONE; | 1136 _state = DONE; |
| 1137 // Stop tracking no pending write events. | 1137 // Stop tracking no pending write events. |
| 1138 _httpConnection.outputStream.noPendingWriteHandler = null; | 1138 _httpConnection.outputStream.onNoPendingWrite = null; |
| 1139 // Ensure that any trailing data is written. | 1139 // Ensure that any trailing data is written. |
| 1140 _writeDone(); | 1140 _writeDone(); |
| 1141 // If the connection is closing then close the output stream to | 1141 // If the connection is closing then close the output stream to |
| 1142 // fully close the socket. | 1142 // fully close the socket. |
| 1143 if (_httpConnection._closing) { | 1143 if (_httpConnection._closing) { |
| 1144 _httpConnection.outputStream.close(); | 1144 _httpConnection.outputStream.close(); |
| 1145 } | 1145 } |
| 1146 } | 1146 } |
| 1147 | 1147 |
| 1148 void _streamSetNoPendingWriteHandler(callback()) { | 1148 void _streamSetNoPendingWriteHandler(callback()) { |
| 1149 if (_state != DONE) { | 1149 if (_state != DONE) { |
| 1150 _httpConnection.outputStream.noPendingWriteHandler = callback; | 1150 _httpConnection.outputStream.onNoPendingWrite = callback; |
| 1151 } | 1151 } |
| 1152 } | 1152 } |
| 1153 | 1153 |
| 1154 void _streamSetCloseHandler(callback()) { | 1154 void _streamSetCloseHandler(callback()) { |
| 1155 // TODO(sgjesse): Handle this. | 1155 // TODO(sgjesse): Handle this. |
| 1156 } | 1156 } |
| 1157 | 1157 |
| 1158 void _streamSetErrorHandler(callback()) { | 1158 void _streamSetErrorHandler(callback()) { |
| 1159 // TODO(sgjesse): Handle this. | 1159 // TODO(sgjesse): Handle this. |
| 1160 } | 1160 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 int get reasonPhrase() { return _reasonPhrase; } | 1208 int get reasonPhrase() { return _reasonPhrase; } |
| 1209 Map get headers() => _headers; | 1209 Map get headers() => _headers; |
| 1210 | 1210 |
| 1211 InputStream get inputStream() { | 1211 InputStream get inputStream() { |
| 1212 if (_inputStream == null) { | 1212 if (_inputStream == null) { |
| 1213 _inputStream = new _HttpInputStream(this); | 1213 _inputStream = new _HttpInputStream(this); |
| 1214 } | 1214 } |
| 1215 return _inputStream; | 1215 return _inputStream; |
| 1216 } | 1216 } |
| 1217 | 1217 |
| 1218 void _requestStartHandler(String method, String uri) { | 1218 void _onRequestStart(String method, String uri) { |
| 1219 // TODO(sgjesse): Error handling | 1219 // TODO(sgjesse): Error handling |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 void _responseStartHandler(int statusCode, String reasonPhrase) { | 1222 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 1223 _statusCode = statusCode; | 1223 _statusCode = statusCode; |
| 1224 _reasonPhrase = reasonPhrase; | 1224 _reasonPhrase = reasonPhrase; |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 void _headerReceivedHandler(String name, String value) { | 1227 void _onHeaderReceived(String name, String value) { |
| 1228 _setHeader(name, value); | 1228 _setHeader(name, value); |
| 1229 } | 1229 } |
| 1230 | 1230 |
| 1231 void _headersCompleteHandler() { | 1231 void _onHeadersComplete() { |
| 1232 _buffer = new _BufferList(); | 1232 _buffer = new _BufferList(); |
| 1233 if (_connection._responseHandler != null) { | 1233 if (_connection._onResponse != null) { |
| 1234 _connection._responseHandler(this); | 1234 _connection._onResponse(this); |
| 1235 } | 1235 } |
| 1236 } | 1236 } |
| 1237 | 1237 |
| 1238 void _dataReceivedHandler(List<int> data) { | 1238 void _onDataReceived(List<int> data) { |
| 1239 _buffer.add(data); | 1239 _buffer.add(data); |
| 1240 if (_inputStream != null) _inputStream._dataReceived(); | 1240 if (_inputStream != null) _inputStream._dataReceived(); |
| 1241 } | 1241 } |
| 1242 | 1242 |
| 1243 void _dataEndHandler() { | 1243 void _onDataEnd() { |
| 1244 if (_inputStream != null) _inputStream._closeReceived(); | 1244 if (_inputStream != null) _inputStream._closeReceived(); |
| 1245 } | 1245 } |
| 1246 | 1246 |
| 1247 // Delegate functions for the HttpInputStream implementation. | 1247 // Delegate functions for the HttpInputStream implementation. |
| 1248 int _streamAvailable() { | 1248 int _streamAvailable() { |
| 1249 return _buffer.length; | 1249 return _buffer.length; |
| 1250 } | 1250 } |
| 1251 | 1251 |
| 1252 List<int> _streamRead(int bytesToRead) { | 1252 List<int> _streamRead(int bytesToRead) { |
| 1253 return _buffer.readBytes(bytesToRead); | 1253 return _buffer.readBytes(bytesToRead); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1270 | 1270 |
| 1271 class _HttpClientConnection | 1271 class _HttpClientConnection |
| 1272 extends _HttpConnectionBase implements HttpClientConnection { | 1272 extends _HttpConnectionBase implements HttpClientConnection { |
| 1273 _HttpClientConnection(_HttpClient this._client); | 1273 _HttpClientConnection(_HttpClient this._client); |
| 1274 | 1274 |
| 1275 void _connectionEstablished(_SocketConnection socketConn) { | 1275 void _connectionEstablished(_SocketConnection socketConn) { |
| 1276 super._connectionEstablished(socketConn._socket); | 1276 super._connectionEstablished(socketConn._socket); |
| 1277 _socketConn = socketConn; | 1277 _socketConn = socketConn; |
| 1278 // Register HTTP parser callbacks. | 1278 // Register HTTP parser callbacks. |
| 1279 _httpParser.requestStart = | 1279 _httpParser.requestStart = |
| 1280 (method, uri) => _requestStartHandler(method, uri); | 1280 (method, uri) => _onRequestStart(method, uri); |
| 1281 _httpParser.responseStart = | 1281 _httpParser.responseStart = |
| 1282 (statusCode, reasonPhrase) => | 1282 (statusCode, reasonPhrase) => |
| 1283 _responseStartHandler(statusCode, reasonPhrase); | 1283 _onResponseStart(statusCode, reasonPhrase); |
| 1284 _httpParser.headerReceived = | 1284 _httpParser.headerReceived = |
| 1285 (name, value) => _headerReceivedHandler(name, value); | 1285 (name, value) => _onHeaderReceived(name, value); |
| 1286 _httpParser.headersComplete = () => _headersCompleteHandler(); | 1286 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 1287 _httpParser.dataReceived = (data) => _dataReceivedHandler(data); | 1287 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 1288 _httpParser.dataEnd = () => _dataEndHandler(); | 1288 _httpParser.dataEnd = () => _onDataEnd(); |
| 1289 } | 1289 } |
| 1290 | 1290 |
| 1291 HttpClientRequest open(String method, String uri) { | 1291 HttpClientRequest open(String method, String uri) { |
| 1292 _request = new _HttpClientRequest(method, uri, this); | 1292 _request = new _HttpClientRequest(method, uri, this); |
| 1293 _request.keepAlive = true; | 1293 _request.keepAlive = true; |
| 1294 _response = new _HttpClientResponse(this); | 1294 _response = new _HttpClientResponse(this); |
| 1295 return _request; | 1295 return _request; |
| 1296 } | 1296 } |
| 1297 | 1297 |
| 1298 void _requestStartHandler(String method, String uri) { | 1298 void _onRequestStart(String method, String uri) { |
| 1299 // TODO(sgjesse): Error handling. | 1299 // TODO(sgjesse): Error handling. |
| 1300 } | 1300 } |
| 1301 | 1301 |
| 1302 void _responseStartHandler(int statusCode, String reasonPhrase) { | 1302 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 1303 _response._responseStartHandler(statusCode, reasonPhrase); | 1303 _response._onResponseStart(statusCode, reasonPhrase); |
| 1304 } | 1304 } |
| 1305 | 1305 |
| 1306 void _headerReceivedHandler(String name, String value) { | 1306 void _onHeaderReceived(String name, String value) { |
| 1307 _response._headerReceivedHandler(name, value); | 1307 _response._onHeaderReceived(name, value); |
| 1308 } | 1308 } |
| 1309 | 1309 |
| 1310 void _headersCompleteHandler() { | 1310 void _onHeadersComplete() { |
| 1311 _response._headersCompleteHandler(); | 1311 _response._onHeadersComplete(); |
| 1312 } | 1312 } |
| 1313 | 1313 |
| 1314 void _dataReceivedHandler(List<int> data) { | 1314 void _onDataReceived(List<int> data) { |
| 1315 _response._dataReceivedHandler(data); | 1315 _response._onDataReceived(data); |
| 1316 } | 1316 } |
| 1317 | 1317 |
| 1318 void _dataEndHandler() { | 1318 void _onDataEnd() { |
| 1319 if (_response.headers["connection"] == "close") { | 1319 if (_response.headers["connection"] == "close") { |
| 1320 _socket.close(); | 1320 _socket.close(); |
| 1321 } else { | 1321 } else { |
| 1322 _client._returnSocketConnection(_socketConn); | 1322 _client._returnSocketConnection(_socketConn); |
| 1323 _socket = null; | 1323 _socket = null; |
| 1324 _socketConn = null; | 1324 _socketConn = null; |
| 1325 } | 1325 } |
| 1326 _response._dataEndHandler(); | 1326 _response._onDataEnd(); |
| 1327 } | 1327 } |
| 1328 | 1328 |
| 1329 void set requestHandler(void handler(HttpClientRequest request)) { | 1329 void set onRequest(void handler(HttpClientRequest request)) { |
| 1330 _requestHandler = handler; | 1330 _onRequest = handler; |
| 1331 } | 1331 } |
| 1332 | 1332 |
| 1333 void set responseHandler(void handler(HttpClientResponse response)) { | 1333 void set onResponse(void handler(HttpClientResponse response)) { |
| 1334 _responseHandler = handler; | 1334 _onResponse = handler; |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 Function _requestHandler; | 1337 Function _onRequest; |
| 1338 Function _responseHandler; | 1338 Function _onResponse; |
| 1339 | 1339 |
| 1340 _HttpClient _client; | 1340 _HttpClient _client; |
| 1341 _SocketConnection _socketConn; | 1341 _SocketConnection _socketConn; |
| 1342 HttpClientRequest _request; | 1342 HttpClientRequest _request; |
| 1343 HttpClientResponse _response; | 1343 HttpClientResponse _response; |
| 1344 | 1344 |
| 1345 // Callbacks. | 1345 // Callbacks. |
| 1346 var requestReceived; | 1346 var requestReceived; |
| 1347 | 1347 |
| 1348 } | 1348 } |
| 1349 | 1349 |
| 1350 | 1350 |
| 1351 // Class for holding keep-alive sockets in the cache for the HTTP | 1351 // Class for holding keep-alive sockets in the cache for the HTTP |
| 1352 // client together with the connection information. | 1352 // client together with the connection information. |
| 1353 class _SocketConnection { | 1353 class _SocketConnection { |
| 1354 _SocketConnection(String this._host, | 1354 _SocketConnection(String this._host, |
| 1355 int this._port, | 1355 int this._port, |
| 1356 Socket this._socket); | 1356 Socket this._socket); |
| 1357 | 1357 |
| 1358 void _markReturned() { | 1358 void _markReturned() { |
| 1359 _socket.dataHandler = null; | 1359 _socket.onData = null; |
| 1360 _socket.closeHandler = null; | 1360 _socket.onClose = null; |
| 1361 _socket.errorHandler = null; | 1361 _socket.onError = null; |
| 1362 _returnTime = new Date.now(); | 1362 _returnTime = new Date.now(); |
| 1363 } | 1363 } |
| 1364 | 1364 |
| 1365 Duration _idleTime(Date now) => now.difference(_returnTime); | 1365 Duration _idleTime(Date now) => now.difference(_returnTime); |
| 1366 | 1366 |
| 1367 String _host; | 1367 String _host; |
| 1368 int _port; | 1368 int _port; |
| 1369 Socket _socket; | 1369 Socket _socket; |
| 1370 Date _returnTime; | 1370 Date _returnTime; |
| 1371 } | 1371 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1408 return "$host:$port"; | 1408 return "$host:$port"; |
| 1409 } | 1409 } |
| 1410 | 1410 |
| 1411 HttpClientConnection _prepareHttpClientConnection( | 1411 HttpClientConnection _prepareHttpClientConnection( |
| 1412 String host, int port, String method, String path) { | 1412 String host, int port, String method, String path) { |
| 1413 | 1413 |
| 1414 void _connectionOpened(_SocketConnection socketConn, | 1414 void _connectionOpened(_SocketConnection socketConn, |
| 1415 _HttpClientConnection connection) { | 1415 _HttpClientConnection connection) { |
| 1416 connection._connectionEstablished(socketConn); | 1416 connection._connectionEstablished(socketConn); |
| 1417 HttpClientRequest request = connection.open(method, path); | 1417 HttpClientRequest request = connection.open(method, path); |
| 1418 if (connection._requestHandler != null) { | 1418 if (connection._onRequest != null) { |
| 1419 connection._requestHandler(request); | 1419 connection._onRequest(request); |
| 1420 } else { | 1420 } else { |
| 1421 request.outputStream.close(); | 1421 request.outputStream.close(); |
| 1422 } | 1422 } |
| 1423 } | 1423 } |
| 1424 | 1424 |
| 1425 _HttpClientConnection connection = new _HttpClientConnection(this); | 1425 _HttpClientConnection connection = new _HttpClientConnection(this); |
| 1426 | 1426 |
| 1427 // If there are active connections for this key get the first one | 1427 // If there are active connections for this key get the first one |
| 1428 // otherwise create a new one. | 1428 // otherwise create a new one. |
| 1429 Queue socketConnections = _openSockets[_connectionKey(host, port)]; | 1429 Queue socketConnections = _openSockets[_connectionKey(host, port)]; |
| 1430 if (socketConnections == null || socketConnections.isEmpty()) { | 1430 if (socketConnections == null || socketConnections.isEmpty()) { |
| 1431 Socket socket = new Socket(host, port); | 1431 Socket socket = new Socket(host, port); |
| 1432 socket.connectHandler = () { | 1432 socket.onConnect = () { |
| 1433 socket.errorHandler = null; | 1433 socket.onError = null; |
| 1434 _SocketConnection socketConn = | 1434 _SocketConnection socketConn = |
| 1435 new _SocketConnection(host, port, socket); | 1435 new _SocketConnection(host, port, socket); |
| 1436 _connectionOpened(socketConn, connection); | 1436 _connectionOpened(socketConn, connection); |
| 1437 }; | 1437 }; |
| 1438 socket.errorHandler = () { | 1438 socket.onError = () { |
| 1439 if (_errorHandler !== null) { | 1439 if (_onError !== null) { |
| 1440 _errorHandler(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR); | 1440 _onError(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR); |
| 1441 } | 1441 } |
| 1442 }; | 1442 }; |
| 1443 } else { | 1443 } else { |
| 1444 _SocketConnection socketConn = socketConnections.removeFirst(); | 1444 _SocketConnection socketConn = socketConnections.removeFirst(); |
| 1445 new Timer((ignored) => _connectionOpened(socketConn, connection), 0); | 1445 new Timer((ignored) => _connectionOpened(socketConn, connection), 0); |
| 1446 | 1446 |
| 1447 // Get rid of eviction timer if there are no more active connections. | 1447 // Get rid of eviction timer if there are no more active connections. |
| 1448 if (socketConnections.isEmpty()) { | 1448 if (socketConnections.isEmpty()) { |
| 1449 _evictionTimer.cancel(); | 1449 _evictionTimer.cancel(); |
| 1450 _evictionTimer = null; | 1450 _evictionTimer = null; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 }); | 1490 }); |
| 1491 } | 1491 } |
| 1492 _evictionTimer = new Timer.repeating(_handleEviction, 10000); | 1492 _evictionTimer = new Timer.repeating(_handleEviction, 10000); |
| 1493 } | 1493 } |
| 1494 | 1494 |
| 1495 // Return connection. | 1495 // Return connection. |
| 1496 sockets.addFirst(socketConn); | 1496 sockets.addFirst(socketConn); |
| 1497 socketConn._markReturned(); | 1497 socketConn._markReturned(); |
| 1498 } | 1498 } |
| 1499 | 1499 |
| 1500 void set errorHandler(void callback(int status)) { | 1500 void set onError(void callback(int status)) { |
| 1501 _errorHandler = callback; | 1501 _onError = callback; |
| 1502 } | 1502 } |
| 1503 | 1503 |
| 1504 Function _openHandler; | 1504 Function _onOpen; |
| 1505 Function _errorHandler; | 1505 Function _onError; |
| 1506 Map<String, Queue<_SocketConnection>> _openSockets; | 1506 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1507 Timer _evictionTimer; | 1507 Timer _evictionTimer; |
| 1508 bool _shutdown; // Has this HTTP client been shutdown? | 1508 bool _shutdown; // Has this HTTP client been shutdown? |
| 1509 } | 1509 } |
| 1510 | 1510 |
| 1511 | 1511 |
| 1512 class HttpUtil { | 1512 class HttpUtil { |
| 1513 static String decodeUrlEncodedString(String urlEncoded) { | 1513 static String decodeUrlEncodedString(String urlEncoded) { |
| 1514 void invalidEscape() { | 1514 void invalidEscape() { |
| 1515 // TODO(sgjesse): Handle the error. | 1515 // TODO(sgjesse): Handle the error. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 } else { | 1560 } else { |
| 1561 value = queryString.substring(currentPosition, position); | 1561 value = queryString.substring(currentPosition, position); |
| 1562 currentPosition = position + 1; | 1562 currentPosition = position + 1; |
| 1563 } | 1563 } |
| 1564 result[HttpUtil.decodeUrlEncodedString(name)] = | 1564 result[HttpUtil.decodeUrlEncodedString(name)] = |
| 1565 HttpUtil.decodeUrlEncodedString(value); | 1565 HttpUtil.decodeUrlEncodedString(value); |
| 1566 } | 1566 } |
| 1567 return result; | 1567 return result; |
| 1568 } | 1568 } |
| 1569 } | 1569 } |
| OLD | NEW |