| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 return _write(buffer, copyBuffer); | 720 return _write(buffer, copyBuffer); |
| 721 } | 721 } |
| 722 | 722 |
| 723 bool _streamWriteFrom(List<int> buffer, int offset, int len) { | 723 bool _streamWriteFrom(List<int> buffer, int offset, int len) { |
| 724 return _writeList(buffer, offset, len); | 724 return _writeList(buffer, offset, len); |
| 725 } | 725 } |
| 726 | 726 |
| 727 void _streamClose() { | 727 void _streamClose() { |
| 728 _state = DONE; | 728 _state = DONE; |
| 729 // Stop tracking no pending write events. | 729 // Stop tracking no pending write events. |
| 730 _httpConnection.outputStream.noPendingWriteHandler = null; | 730 _httpConnection.outputStream.onNoPendingWrites = null; |
| 731 // Ensure that any trailing data is written. | 731 // Ensure that any trailing data is written. |
| 732 _writeDone(); | 732 _writeDone(); |
| 733 // If the connection is closing then close the output stream to | 733 // If the connection is closing then close the output stream to |
| 734 // fully close the socket. | 734 // fully close the socket. |
| 735 if (_httpConnection._closing) { | 735 if (_httpConnection._closing) { |
| 736 _httpConnection.outputStream.close(); | 736 _httpConnection.outputStream.close(); |
| 737 } | 737 } |
| 738 } | 738 } |
| 739 | 739 |
| 740 void _streamSetNoPendingWriteHandler(callback()) { | 740 void _streamSetNoPendingWriteHandler(callback()) { |
| 741 if (_state != DONE) { | 741 if (_state != DONE) { |
| 742 _httpConnection.outputStream.noPendingWriteHandler = callback; | 742 _httpConnection.outputStream.onNoPendingWrites = callback; |
| 743 } | 743 } |
| 744 } | 744 } |
| 745 | 745 |
| 746 void _streamSetCloseHandler(callback()) { | 746 void _streamSetCloseHandler(callback()) { |
| 747 // TODO(sgjesse): Handle this. | 747 // TODO(sgjesse): Handle this. |
| 748 } | 748 } |
| 749 | 749 |
| 750 void _streamSetErrorHandler(callback()) { | 750 void _streamSetErrorHandler(callback()) { |
| 751 // TODO(sgjesse): Handle this. | 751 // TODO(sgjesse): Handle this. |
| 752 } | 752 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 } | 894 } |
| 895 | 895 |
| 896 void close() { | 896 void close() { |
| 897 _requestOrResponse._streamClose(); | 897 _requestOrResponse._streamClose(); |
| 898 } | 898 } |
| 899 | 899 |
| 900 void destroy() { | 900 void destroy() { |
| 901 throw "Not implemented"; | 901 throw "Not implemented"; |
| 902 } | 902 } |
| 903 | 903 |
| 904 void set noPendingWriteHandler(void callback()) { | 904 void set onNoPendingWrites(void callback()) { |
| 905 _requestOrResponse._streamSetNoPendingWriteHandler(callback); | 905 _requestOrResponse._streamSetNoPendingWriteHandler(callback); |
| 906 } | 906 } |
| 907 | 907 |
| 908 void set closeHandler(void callback()) { | 908 void set onClosed(void callback()) { |
| 909 _requestOrResponse._streamSetCloseHandler(callback); | 909 _requestOrResponse._streamSetCloseHandler(callback); |
| 910 } | 910 } |
| 911 | 911 |
| 912 void set errorHandler(void callback()) { | 912 void set onError(void callback()) { |
| 913 _requestOrResponse._streamSetErrorHandler(callback); | 913 _requestOrResponse._streamSetErrorHandler(callback); |
| 914 } | 914 } |
| 915 | 915 |
| 916 _HttpRequestResponseBase _requestOrResponse; | 916 _HttpRequestResponseBase _requestOrResponse; |
| 917 } | 917 } |
| 918 | 918 |
| 919 | 919 |
| 920 class _HttpConnectionBase { | 920 class _HttpConnectionBase { |
| 921 _HttpConnectionBase() : _sendBuffers = new Queue(), | 921 _HttpConnectionBase() : _sendBuffers = new Queue(), |
| 922 _httpParser = new HttpParser(); | 922 _httpParser = new HttpParser(); |
| 923 | 923 |
| 924 void _connectionEstablished(Socket socket) { | 924 void _connectionEstablished(Socket socket) { |
| 925 _socket = socket; | 925 _socket = socket; |
| 926 // Register handler for socket events. | 926 // Register handler for socket events. |
| 927 _socket.dataHandler = _dataHandler; | 927 _socket.onData = _onData; |
| 928 _socket.closeHandler = _closeHandler; | 928 _socket.onClosed = _onClosed; |
| 929 _socket.errorHandler = _errorHandler; | 929 _socket.onError = _onError; |
| 930 } | 930 } |
| 931 | 931 |
| 932 OutputStream get outputStream() { | 932 OutputStream get outputStream() { |
| 933 return _socket.outputStream; | 933 return _socket.outputStream; |
| 934 } | 934 } |
| 935 | 935 |
| 936 void _dataHandler() { | 936 void _onData() { |
| 937 int available = _socket.available(); | 937 int available = _socket.available(); |
| 938 if (available == 0) { | 938 if (available == 0) { |
| 939 return; | 939 return; |
| 940 } | 940 } |
| 941 | 941 |
| 942 ByteArray buffer = new ByteArray(available); | 942 ByteArray buffer = new ByteArray(available); |
| 943 int bytesRead = _socket.readList(buffer, 0, available); | 943 int bytesRead = _socket.readList(buffer, 0, available); |
| 944 if (bytesRead > 0) { | 944 if (bytesRead > 0) { |
| 945 int parsed = _httpParser.writeList(buffer, 0, bytesRead); | 945 int parsed = _httpParser.writeList(buffer, 0, bytesRead); |
| 946 if (parsed != bytesRead) { | 946 if (parsed != bytesRead) { |
| 947 // TODO(sgjesse): Error handling. | 947 // TODO(sgjesse): Error handling. |
| 948 _socket.close(); | 948 _socket.close(); |
| 949 } | 949 } |
| 950 } | 950 } |
| 951 } | 951 } |
| 952 | 952 |
| 953 void _closeHandler() { | 953 void _onClosed() { |
| 954 // Client closed socket for writing. Socket should still be open | 954 // Client closed socket for writing. Socket should still be open |
| 955 // for writing the response. | 955 // for writing the response. |
| 956 _closing = true; | 956 _closing = true; |
| 957 if (_disconnectHandlerCallback != null) _disconnectHandlerCallback(); | 957 if (_onDisconnectCallback != null) _onDisconnectCallback(); |
| 958 } | 958 } |
| 959 | 959 |
| 960 void _errorHandler() { | 960 void _onError() { |
| 961 // If an error occours, treat the socket as closed. | 961 // If an error occours, treat the socket as closed. |
| 962 _closeHandler(); | 962 _onClosed(); |
| 963 if (_errorHandlerCallback != null) { | 963 if (_onErrorCallback != null) { |
| 964 _errorHandlerCallback("Connection closed while sending data to client."); | 964 _onErrorCallback("Connection closed while sending data to client."); |
| 965 } | 965 } |
| 966 } | 966 } |
| 967 | 967 |
| 968 void set disconnectHandler(void callback()) { | 968 void set onDisconnect(void callback()) { |
| 969 _disconnectHandlerCallback = callback; | 969 _onDisconnectCallback = callback; |
| 970 } | 970 } |
| 971 | 971 |
| 972 void set errorHandler(void callback(String errorMessage)) { | 972 void set onError(void callback(String errorMessage)) { |
| 973 _errorHandlerCallback = callback; | 973 _onErrorCallback = callback; |
| 974 } | 974 } |
| 975 | 975 |
| 976 Socket _socket; | 976 Socket _socket; |
| 977 bool _closing = false; // Is the socket closed by the client? | 977 bool _closing = false; // Is the socket closed by the client? |
| 978 HttpParser _httpParser; | 978 HttpParser _httpParser; |
| 979 | 979 |
| 980 Queue _sendBuffers; | 980 Queue _sendBuffers; |
| 981 | 981 |
| 982 Function _disconnectHandlerCallback; | 982 Function _onDisconnectCallback; |
| 983 Function _errorHandlerCallback; | 983 Function _onErrorCallback; |
| 984 } | 984 } |
| 985 | 985 |
| 986 | 986 |
| 987 // HTTP server connection over a socket. | 987 // HTTP server connection over a socket. |
| 988 class _HttpConnection extends _HttpConnectionBase { | 988 class _HttpConnection extends _HttpConnectionBase { |
| 989 _HttpConnection() { | 989 _HttpConnection() { |
| 990 // Register HTTP parser callbacks. | 990 // Register HTTP parser callbacks. |
| 991 _httpParser.requestStart = | 991 _httpParser.requestStart = |
| 992 (method, uri) => _requestStartHandler(method, uri); | 992 (method, uri) => _onRequestStart(method, uri); |
| 993 _httpParser.responseStart = | 993 _httpParser.responseStart = |
| 994 (statusCode, reasonPhrase) => | 994 (statusCode, reasonPhrase) => |
| 995 _responseStartHandler(statusCode, reasonPhrase); | 995 _onResponseStart(statusCode, reasonPhrase); |
| 996 _httpParser.headerReceived = | 996 _httpParser.headerReceived = |
| 997 (name, value) => _headerReceivedHandler(name, value); | 997 (name, value) => _onHeaderReceived(name, value); |
| 998 _httpParser.headersComplete = () => _headersCompleteHandler(); | 998 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 999 _httpParser.dataReceived = (data) => _dataReceivedHandler(data); | 999 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 1000 _httpParser.dataEnd = () => _dataEndHandler(); | 1000 _httpParser.dataEnd = () => _onDataEnd(); |
| 1001 } | 1001 } |
| 1002 | 1002 |
| 1003 void _requestStartHandler(String method, String uri) { | 1003 void _onRequestStart(String method, String uri) { |
| 1004 // Create new request and response objects for this request. | 1004 // Create new request and response objects for this request. |
| 1005 _request = new _HttpRequest(this); | 1005 _request = new _HttpRequest(this); |
| 1006 _response = new _HttpResponse(this); | 1006 _response = new _HttpResponse(this); |
| 1007 _request._requestStartHandler(method, uri); | 1007 _request._onRequestStart(method, uri); |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 void _responseStartHandler(int statusCode, String reasonPhrase) { | 1010 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 1011 // TODO(sgjesse): Error handling. | 1011 // TODO(sgjesse): Error handling. |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 void _headerReceivedHandler(String name, String value) { | 1014 void _onHeaderReceived(String name, String value) { |
| 1015 _request._headerReceivedHandler(name, value); | 1015 _request._onHeaderReceived(name, value); |
| 1016 } | 1016 } |
| 1017 | 1017 |
| 1018 void _headersCompleteHandler() { | 1018 void _onHeadersComplete() { |
| 1019 _request._headersCompleteHandler(); | 1019 _request._onHeadersComplete(); |
| 1020 _response.keepAlive = _httpParser.keepAlive; | 1020 _response.keepAlive = _httpParser.keepAlive; |
| 1021 if (requestReceived != null) { | 1021 if (requestReceived != null) { |
| 1022 requestReceived(_request, _response); | 1022 requestReceived(_request, _response); |
| 1023 } | 1023 } |
| 1024 } | 1024 } |
| 1025 | 1025 |
| 1026 void _dataReceivedHandler(List<int> data) { | 1026 void _onDataReceived(List<int> data) { |
| 1027 _request._dataReceivedHandler(data); | 1027 _request._onDataReceived(data); |
| 1028 } | 1028 } |
| 1029 | 1029 |
| 1030 void _dataEndHandler() { | 1030 void _onDataEnd() { |
| 1031 _request._dataEndHandler(); | 1031 _request._onDataEnd(); |
| 1032 } | 1032 } |
| 1033 | 1033 |
| 1034 HttpRequest _request; | 1034 HttpRequest _request; |
| 1035 HttpResponse _response; | 1035 HttpResponse _response; |
| 1036 | 1036 |
| 1037 // Callbacks. | 1037 // Callbacks. |
| 1038 var requestReceived; | 1038 var requestReceived; |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 | 1041 |
| 1042 // HTTP server waiting for socket connections. The connections are | 1042 // HTTP server waiting for socket connections. The connections are |
| 1043 // managed by the server and as requests are received the request. | 1043 // managed by the server and as requests are received the request. |
| 1044 class _HttpServer implements HttpServer { | 1044 class _HttpServer implements HttpServer { |
| 1045 void listen(String host, int port, [int backlog = 5]) { | 1045 void listen(String host, int port, [int backlog = 5]) { |
| 1046 | 1046 |
| 1047 void connectionHandler(Socket socket) { | 1047 void onConnection(Socket socket) { |
| 1048 // Accept the client connection. | 1048 // Accept the client connection. |
| 1049 _HttpConnection connection = new _HttpConnection(); | 1049 _HttpConnection connection = new _HttpConnection(); |
| 1050 connection._connectionEstablished(socket); | 1050 connection._connectionEstablished(socket); |
| 1051 connection.requestReceived = _requestHandler; | 1051 connection.requestReceived = _onRequest; |
| 1052 _connections.add(connection); | 1052 _connections.add(connection); |
| 1053 void disconnectHandler() { | 1053 void onDisconnect() { |
| 1054 for (int i = 0; i < _connections.length; i++) { | 1054 for (int i = 0; i < _connections.length; i++) { |
| 1055 if (_connections[i] == connection) { | 1055 if (_connections[i] == connection) { |
| 1056 _connections.removeRange(i, 1); | 1056 _connections.removeRange(i, 1); |
| 1057 break; | 1057 break; |
| 1058 } | 1058 } |
| 1059 } | 1059 } |
| 1060 } | 1060 } |
| 1061 connection.disconnectHandler = disconnectHandler; | 1061 connection.onDisconnect = onDisconnect; |
| 1062 void errorHandler(String errorMessage) { | 1062 void onError(String errorMessage) { |
| 1063 if (_errorHandler != null) _errorHandler(errorMessage); | 1063 if (_onError != null) _onError(errorMessage); |
| 1064 } | 1064 } |
| 1065 connection.errorHandler = errorHandler; | 1065 connection.onError = onError; |
| 1066 } | 1066 } |
| 1067 | 1067 |
| 1068 // TODO(ajohnsen): Use Set once Socket is Hashable. | 1068 // TODO(ajohnsen): Use Set once Socket is Hashable. |
| 1069 _connections = new List<_HttpConnection>(); | 1069 _connections = new List<_HttpConnection>(); |
| 1070 _server = new ServerSocket(host, port, backlog); | 1070 _server = new ServerSocket(host, port, backlog); |
| 1071 _server.connectionHandler = connectionHandler; | 1071 _server.onConnection = onConnection; |
| 1072 } | 1072 } |
| 1073 | 1073 |
| 1074 void close() => _server.close(); | 1074 void close() => _server.close(); |
| 1075 int get port() => _server.port; | 1075 int get port() => _server.port; |
| 1076 | 1076 |
| 1077 void set errorHandler(void handler(String errorMessage)) { | 1077 void set onError(void handler(String errorMessage)) { |
| 1078 _errorHandler = handler; | 1078 _onError = handler; |
| 1079 } | 1079 } |
| 1080 | 1080 |
| 1081 void set requestHandler(void handler(HttpRequest, HttpResponse)) { | 1081 void set onRequest(void handler(HttpRequest, HttpResponse)) { |
| 1082 _requestHandler = handler; | 1082 _onRequest = handler; |
| 1083 } | 1083 } |
| 1084 | 1084 |
| 1085 ServerSocket _server; // The server listen socket. | 1085 ServerSocket _server; // The server listen socket. |
| 1086 List<_HttpConnection> _connections; // List of currently connected clients. | 1086 List<_HttpConnection> _connections; // List of currently connected clients. |
| 1087 Function _requestHandler; | 1087 Function _onRequest; |
| 1088 Function _errorHandler; | 1088 Function _onError; |
| 1089 } | 1089 } |
| 1090 | 1090 |
| 1091 | 1091 |
| 1092 class _HttpClientRequest | 1092 class _HttpClientRequest |
| 1093 extends _HttpRequestResponseBase implements HttpClientRequest { | 1093 extends _HttpRequestResponseBase implements HttpClientRequest { |
| 1094 static final int START = 0; | 1094 static final int START = 0; |
| 1095 static final int HEADERS_SENT = 1; | 1095 static final int HEADERS_SENT = 1; |
| 1096 static final int DONE = 2; | 1096 static final int DONE = 2; |
| 1097 | 1097 |
| 1098 _HttpClientRequest(String this._method, | 1098 _HttpClientRequest(String this._method, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 return _write(buffer, copyBuffer); | 1136 return _write(buffer, copyBuffer); |
| 1137 } | 1137 } |
| 1138 | 1138 |
| 1139 bool _streamWriteFrom(List<int> buffer, int offset, int len) { | 1139 bool _streamWriteFrom(List<int> buffer, int offset, int len) { |
| 1140 return _writeList(buffer, offset, len); | 1140 return _writeList(buffer, offset, len); |
| 1141 } | 1141 } |
| 1142 | 1142 |
| 1143 void _streamClose() { | 1143 void _streamClose() { |
| 1144 _state = DONE; | 1144 _state = DONE; |
| 1145 // Stop tracking no pending write events. | 1145 // Stop tracking no pending write events. |
| 1146 _httpConnection.outputStream.noPendingWriteHandler = null; | 1146 _httpConnection.outputStream.onNoPendingWrites = null; |
| 1147 // Ensure that any trailing data is written. | 1147 // Ensure that any trailing data is written. |
| 1148 _writeDone(); | 1148 _writeDone(); |
| 1149 // If the connection is closing then close the output stream to | 1149 // If the connection is closing then close the output stream to |
| 1150 // fully close the socket. | 1150 // fully close the socket. |
| 1151 if (_httpConnection._closing) { | 1151 if (_httpConnection._closing) { |
| 1152 _httpConnection.outputStream.close(); | 1152 _httpConnection.outputStream.close(); |
| 1153 } | 1153 } |
| 1154 } | 1154 } |
| 1155 | 1155 |
| 1156 void _streamSetNoPendingWriteHandler(callback()) { | 1156 void _streamSetNoPendingWriteHandler(callback()) { |
| 1157 if (_state != DONE) { | 1157 if (_state != DONE) { |
| 1158 _httpConnection.outputStream.noPendingWriteHandler = callback; | 1158 _httpConnection.outputStream.onNoPendingWrites = callback; |
| 1159 } | 1159 } |
| 1160 } | 1160 } |
| 1161 | 1161 |
| 1162 void _streamSetCloseHandler(callback()) { | 1162 void _streamSetCloseHandler(callback()) { |
| 1163 // TODO(sgjesse): Handle this. | 1163 // TODO(sgjesse): Handle this. |
| 1164 } | 1164 } |
| 1165 | 1165 |
| 1166 void _streamSetErrorHandler(callback()) { | 1166 void _streamSetErrorHandler(callback()) { |
| 1167 // TODO(sgjesse): Handle this. | 1167 // TODO(sgjesse): Handle this. |
| 1168 } | 1168 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 String get reasonPhrase() => _reasonPhrase; | 1216 String get reasonPhrase() => _reasonPhrase; |
| 1217 Map get headers() => _headers; | 1217 Map get headers() => _headers; |
| 1218 | 1218 |
| 1219 InputStream get inputStream() { | 1219 InputStream get inputStream() { |
| 1220 if (_inputStream == null) { | 1220 if (_inputStream == null) { |
| 1221 _inputStream = new _HttpInputStream(this); | 1221 _inputStream = new _HttpInputStream(this); |
| 1222 } | 1222 } |
| 1223 return _inputStream; | 1223 return _inputStream; |
| 1224 } | 1224 } |
| 1225 | 1225 |
| 1226 void _requestStartHandler(String method, String uri) { | 1226 void _onRequestStart(String method, String uri) { |
| 1227 // TODO(sgjesse): Error handling | 1227 // TODO(sgjesse): Error handling |
| 1228 } | 1228 } |
| 1229 | 1229 |
| 1230 void _responseStartHandler(int statusCode, String reasonPhrase) { | 1230 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 1231 _statusCode = statusCode; | 1231 _statusCode = statusCode; |
| 1232 _reasonPhrase = reasonPhrase; | 1232 _reasonPhrase = reasonPhrase; |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 void _headerReceivedHandler(String name, String value) { | 1235 void _onHeaderReceived(String name, String value) { |
| 1236 _setHeader(name, value); | 1236 _setHeader(name, value); |
| 1237 } | 1237 } |
| 1238 | 1238 |
| 1239 void _headersCompleteHandler() { | 1239 void _onHeadersComplete() { |
| 1240 _buffer = new _BufferList(); | 1240 _buffer = new _BufferList(); |
| 1241 if (_connection._responseHandler != null) { | 1241 if (_connection._onResponse != null) { |
| 1242 _connection._responseHandler(this); | 1242 _connection._onResponse(this); |
| 1243 } | 1243 } |
| 1244 } | 1244 } |
| 1245 | 1245 |
| 1246 void _dataReceivedHandler(List<int> data) { | 1246 void _onDataReceived(List<int> data) { |
| 1247 _buffer.add(data); | 1247 _buffer.add(data); |
| 1248 if (_inputStream != null) _inputStream._dataReceived(); | 1248 if (_inputStream != null) _inputStream._dataReceived(); |
| 1249 } | 1249 } |
| 1250 | 1250 |
| 1251 void _dataEndHandler() { | 1251 void _onDataEnd() { |
| 1252 if (_inputStream != null) _inputStream._closeReceived(); | 1252 if (_inputStream != null) _inputStream._closeReceived(); |
| 1253 } | 1253 } |
| 1254 | 1254 |
| 1255 // Delegate functions for the HttpInputStream implementation. | 1255 // Delegate functions for the HttpInputStream implementation. |
| 1256 int _streamAvailable() { | 1256 int _streamAvailable() { |
| 1257 return _buffer.length; | 1257 return _buffer.length; |
| 1258 } | 1258 } |
| 1259 | 1259 |
| 1260 List<int> _streamRead(int bytesToRead) { | 1260 List<int> _streamRead(int bytesToRead) { |
| 1261 return _buffer.readBytes(bytesToRead); | 1261 return _buffer.readBytes(bytesToRead); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1278 | 1278 |
| 1279 class _HttpClientConnection | 1279 class _HttpClientConnection |
| 1280 extends _HttpConnectionBase implements HttpClientConnection { | 1280 extends _HttpConnectionBase implements HttpClientConnection { |
| 1281 _HttpClientConnection(_HttpClient this._client); | 1281 _HttpClientConnection(_HttpClient this._client); |
| 1282 | 1282 |
| 1283 void _connectionEstablished(_SocketConnection socketConn) { | 1283 void _connectionEstablished(_SocketConnection socketConn) { |
| 1284 super._connectionEstablished(socketConn._socket); | 1284 super._connectionEstablished(socketConn._socket); |
| 1285 _socketConn = socketConn; | 1285 _socketConn = socketConn; |
| 1286 // Register HTTP parser callbacks. | 1286 // Register HTTP parser callbacks. |
| 1287 _httpParser.requestStart = | 1287 _httpParser.requestStart = |
| 1288 (method, uri) => _requestStartHandler(method, uri); | 1288 (method, uri) => _onRequestStart(method, uri); |
| 1289 _httpParser.responseStart = | 1289 _httpParser.responseStart = |
| 1290 (statusCode, reasonPhrase) => | 1290 (statusCode, reasonPhrase) => |
| 1291 _responseStartHandler(statusCode, reasonPhrase); | 1291 _onResponseStart(statusCode, reasonPhrase); |
| 1292 _httpParser.headerReceived = | 1292 _httpParser.headerReceived = |
| 1293 (name, value) => _headerReceivedHandler(name, value); | 1293 (name, value) => _onHeaderReceived(name, value); |
| 1294 _httpParser.headersComplete = () => _headersCompleteHandler(); | 1294 _httpParser.headersComplete = () => _onHeadersComplete(); |
| 1295 _httpParser.dataReceived = (data) => _dataReceivedHandler(data); | 1295 _httpParser.dataReceived = (data) => _onDataReceived(data); |
| 1296 _httpParser.dataEnd = () => _dataEndHandler(); | 1296 _httpParser.dataEnd = () => _onDataEnd(); |
| 1297 } | 1297 } |
| 1298 | 1298 |
| 1299 HttpClientRequest open(String method, String uri) { | 1299 HttpClientRequest open(String method, String uri) { |
| 1300 _request = new _HttpClientRequest(method, uri, this); | 1300 _request = new _HttpClientRequest(method, uri, this); |
| 1301 _request.keepAlive = true; | 1301 _request.keepAlive = true; |
| 1302 _response = new _HttpClientResponse(this); | 1302 _response = new _HttpClientResponse(this); |
| 1303 return _request; | 1303 return _request; |
| 1304 } | 1304 } |
| 1305 | 1305 |
| 1306 void _requestStartHandler(String method, String uri) { | 1306 void _onRequestStart(String method, String uri) { |
| 1307 // TODO(sgjesse): Error handling. | 1307 // TODO(sgjesse): Error handling. |
| 1308 } | 1308 } |
| 1309 | 1309 |
| 1310 void _responseStartHandler(int statusCode, String reasonPhrase) { | 1310 void _onResponseStart(int statusCode, String reasonPhrase) { |
| 1311 _response._responseStartHandler(statusCode, reasonPhrase); | 1311 _response._onResponseStart(statusCode, reasonPhrase); |
| 1312 } | 1312 } |
| 1313 | 1313 |
| 1314 void _headerReceivedHandler(String name, String value) { | 1314 void _onHeaderReceived(String name, String value) { |
| 1315 _response._headerReceivedHandler(name, value); | 1315 _response._onHeaderReceived(name, value); |
| 1316 } | 1316 } |
| 1317 | 1317 |
| 1318 void _headersCompleteHandler() { | 1318 void _onHeadersComplete() { |
| 1319 _response._headersCompleteHandler(); | 1319 _response._onHeadersComplete(); |
| 1320 } | 1320 } |
| 1321 | 1321 |
| 1322 void _dataReceivedHandler(List<int> data) { | 1322 void _onDataReceived(List<int> data) { |
| 1323 _response._dataReceivedHandler(data); | 1323 _response._onDataReceived(data); |
| 1324 } | 1324 } |
| 1325 | 1325 |
| 1326 void _dataEndHandler() { | 1326 void _onDataEnd() { |
| 1327 if (_response.headers["connection"] == "close") { | 1327 if (_response.headers["connection"] == "close") { |
| 1328 _socket.close(); | 1328 _socket.close(); |
| 1329 } else { | 1329 } else { |
| 1330 _client._returnSocketConnection(_socketConn); | 1330 _client._returnSocketConnection(_socketConn); |
| 1331 _socket = null; | 1331 _socket = null; |
| 1332 _socketConn = null; | 1332 _socketConn = null; |
| 1333 } | 1333 } |
| 1334 _response._dataEndHandler(); | 1334 _response._onDataEnd(); |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 void set requestHandler(void handler(HttpClientRequest request)) { | 1337 void set onRequest(void handler(HttpClientRequest request)) { |
| 1338 _requestHandler = handler; | 1338 _onRequest = handler; |
| 1339 } | 1339 } |
| 1340 | 1340 |
| 1341 void set responseHandler(void handler(HttpClientResponse response)) { | 1341 void set onResponse(void handler(HttpClientResponse response)) { |
| 1342 _responseHandler = handler; | 1342 _onResponse = handler; |
| 1343 } | 1343 } |
| 1344 | 1344 |
| 1345 Function _requestHandler; | 1345 Function _onRequest; |
| 1346 Function _responseHandler; | 1346 Function _onResponse; |
| 1347 | 1347 |
| 1348 _HttpClient _client; | 1348 _HttpClient _client; |
| 1349 _SocketConnection _socketConn; | 1349 _SocketConnection _socketConn; |
| 1350 HttpClientRequest _request; | 1350 HttpClientRequest _request; |
| 1351 HttpClientResponse _response; | 1351 HttpClientResponse _response; |
| 1352 | 1352 |
| 1353 // Callbacks. | 1353 // Callbacks. |
| 1354 var requestReceived; | 1354 var requestReceived; |
| 1355 | 1355 |
| 1356 } | 1356 } |
| 1357 | 1357 |
| 1358 | 1358 |
| 1359 // Class for holding keep-alive sockets in the cache for the HTTP | 1359 // Class for holding keep-alive sockets in the cache for the HTTP |
| 1360 // client together with the connection information. | 1360 // client together with the connection information. |
| 1361 class _SocketConnection { | 1361 class _SocketConnection { |
| 1362 _SocketConnection(String this._host, | 1362 _SocketConnection(String this._host, |
| 1363 int this._port, | 1363 int this._port, |
| 1364 Socket this._socket); | 1364 Socket this._socket); |
| 1365 | 1365 |
| 1366 void _markReturned() { | 1366 void _markReturned() { |
| 1367 _socket.dataHandler = null; | 1367 _socket.onData = null; |
| 1368 _socket.closeHandler = null; | 1368 _socket.onClosed = null; |
| 1369 _socket.errorHandler = null; | 1369 _socket.onError = null; |
| 1370 _returnTime = new Date.now(); | 1370 _returnTime = new Date.now(); |
| 1371 } | 1371 } |
| 1372 | 1372 |
| 1373 Duration _idleTime(Date now) => now.difference(_returnTime); | 1373 Duration _idleTime(Date now) => now.difference(_returnTime); |
| 1374 | 1374 |
| 1375 String _host; | 1375 String _host; |
| 1376 int _port; | 1376 int _port; |
| 1377 Socket _socket; | 1377 Socket _socket; |
| 1378 Date _returnTime; | 1378 Date _returnTime; |
| 1379 } | 1379 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 return "$host:$port"; | 1416 return "$host:$port"; |
| 1417 } | 1417 } |
| 1418 | 1418 |
| 1419 HttpClientConnection _prepareHttpClientConnection( | 1419 HttpClientConnection _prepareHttpClientConnection( |
| 1420 String host, int port, String method, String path) { | 1420 String host, int port, String method, String path) { |
| 1421 | 1421 |
| 1422 void _connectionOpened(_SocketConnection socketConn, | 1422 void _connectionOpened(_SocketConnection socketConn, |
| 1423 _HttpClientConnection connection) { | 1423 _HttpClientConnection connection) { |
| 1424 connection._connectionEstablished(socketConn); | 1424 connection._connectionEstablished(socketConn); |
| 1425 HttpClientRequest request = connection.open(method, path); | 1425 HttpClientRequest request = connection.open(method, path); |
| 1426 if (connection._requestHandler != null) { | 1426 if (connection._onRequest != null) { |
| 1427 connection._requestHandler(request); | 1427 connection._onRequest(request); |
| 1428 } else { | 1428 } else { |
| 1429 request.outputStream.close(); | 1429 request.outputStream.close(); |
| 1430 } | 1430 } |
| 1431 } | 1431 } |
| 1432 | 1432 |
| 1433 _HttpClientConnection connection = new _HttpClientConnection(this); | 1433 _HttpClientConnection connection = new _HttpClientConnection(this); |
| 1434 | 1434 |
| 1435 // If there are active connections for this key get the first one | 1435 // If there are active connections for this key get the first one |
| 1436 // otherwise create a new one. | 1436 // otherwise create a new one. |
| 1437 Queue socketConnections = _openSockets[_connectionKey(host, port)]; | 1437 Queue socketConnections = _openSockets[_connectionKey(host, port)]; |
| 1438 if (socketConnections == null || socketConnections.isEmpty()) { | 1438 if (socketConnections == null || socketConnections.isEmpty()) { |
| 1439 Socket socket = new Socket(host, port); | 1439 Socket socket = new Socket(host, port); |
| 1440 socket.connectHandler = () { | 1440 socket.onConnect = () { |
| 1441 socket.errorHandler = null; | 1441 socket.onError = null; |
| 1442 _SocketConnection socketConn = | 1442 _SocketConnection socketConn = |
| 1443 new _SocketConnection(host, port, socket); | 1443 new _SocketConnection(host, port, socket); |
| 1444 _connectionOpened(socketConn, connection); | 1444 _connectionOpened(socketConn, connection); |
| 1445 }; | 1445 }; |
| 1446 socket.errorHandler = () { | 1446 socket.onError = () { |
| 1447 if (_errorHandler !== null) { | 1447 if (_onError !== null) { |
| 1448 _errorHandler(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR); | 1448 _onError(HttpStatus.NETWORK_CONNECT_TIMEOUT_ERROR); |
| 1449 } | 1449 } |
| 1450 }; | 1450 }; |
| 1451 } else { | 1451 } else { |
| 1452 _SocketConnection socketConn = socketConnections.removeFirst(); | 1452 _SocketConnection socketConn = socketConnections.removeFirst(); |
| 1453 new Timer((ignored) => _connectionOpened(socketConn, connection), 0); | 1453 new Timer((ignored) => _connectionOpened(socketConn, connection), 0); |
| 1454 | 1454 |
| 1455 // Get rid of eviction timer if there are no more active connections. | 1455 // Get rid of eviction timer if there are no more active connections. |
| 1456 if (socketConnections.isEmpty()) { | 1456 if (socketConnections.isEmpty()) { |
| 1457 _evictionTimer.cancel(); | 1457 _evictionTimer.cancel(); |
| 1458 _evictionTimer = null; | 1458 _evictionTimer = null; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 }); | 1498 }); |
| 1499 } | 1499 } |
| 1500 _evictionTimer = new Timer.repeating(_handleEviction, 10000); | 1500 _evictionTimer = new Timer.repeating(_handleEviction, 10000); |
| 1501 } | 1501 } |
| 1502 | 1502 |
| 1503 // Return connection. | 1503 // Return connection. |
| 1504 sockets.addFirst(socketConn); | 1504 sockets.addFirst(socketConn); |
| 1505 socketConn._markReturned(); | 1505 socketConn._markReturned(); |
| 1506 } | 1506 } |
| 1507 | 1507 |
| 1508 void set errorHandler(void callback(int status)) { | 1508 void set onError(void callback(int status)) { |
| 1509 _errorHandler = callback; | 1509 _onError = callback; |
| 1510 } | 1510 } |
| 1511 | 1511 |
| 1512 Function _openHandler; | 1512 Function _onOpen; |
| 1513 Function _errorHandler; | 1513 Function _onError; |
| 1514 Map<String, Queue<_SocketConnection>> _openSockets; | 1514 Map<String, Queue<_SocketConnection>> _openSockets; |
| 1515 Timer _evictionTimer; | 1515 Timer _evictionTimer; |
| 1516 bool _shutdown; // Has this HTTP client been shutdown? | 1516 bool _shutdown; // Has this HTTP client been shutdown? |
| 1517 } | 1517 } |
| 1518 | 1518 |
| 1519 | 1519 |
| 1520 class HttpUtil { | 1520 class HttpUtil { |
| 1521 static String decodeUrlEncodedString(String urlEncoded) { | 1521 static String decodeUrlEncodedString(String urlEncoded) { |
| 1522 void invalidEscape() { | 1522 void invalidEscape() { |
| 1523 // TODO(sgjesse): Handle the error. | 1523 // TODO(sgjesse): Handle the error. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 } else { | 1568 } else { |
| 1569 value = queryString.substring(currentPosition, position); | 1569 value = queryString.substring(currentPosition, position); |
| 1570 currentPosition = position + 1; | 1570 currentPosition = position + 1; |
| 1571 } | 1571 } |
| 1572 result[HttpUtil.decodeUrlEncodedString(name)] = | 1572 result[HttpUtil.decodeUrlEncodedString(name)] = |
| 1573 HttpUtil.decodeUrlEncodedString(value); | 1573 HttpUtil.decodeUrlEncodedString(value); |
| 1574 } | 1574 } |
| 1575 return result; | 1575 return result; |
| 1576 } | 1576 } |
| 1577 } | 1577 } |
| OLD | NEW |