| Index: sdk/lib/io/tls_socket.dart
|
| diff --git a/sdk/lib/io/tls_socket.dart b/sdk/lib/io/tls_socket.dart
|
| index 9f3e292c779aefc394464eb6d4398c3dbe40ff52..051e63a144da453f187d7dd5a04cb40adc1107cb 100644
|
| --- a/sdk/lib/io/tls_socket.dart
|
| +++ b/sdk/lib/io/tls_socket.dart
|
| @@ -82,11 +82,6 @@ class _TlsSocket implements TlsSocket {
|
| _tlsFilter.registerHandshakeCompleteCallback(_tlsHandshakeCompleteHandler);
|
| }
|
|
|
| - InputStream get inputStream {
|
| - // TODO(6701): Implement stream interfaces on TlsSocket.
|
| - throw new UnimplementedError("TlsSocket.inputStream not implemented yet");
|
| - }
|
| -
|
| int get port => _socket.port;
|
|
|
| String get remoteHost => _socket.remoteHost;
|
| @@ -94,26 +89,79 @@ class _TlsSocket implements TlsSocket {
|
| int get remotePort => _socket.remotePort;
|
|
|
| void set onClosed(void callback()) {
|
| + if (_inputStream != null) {
|
| + throw new StreamException(
|
| + "Cannot set close handler when input stream is used");
|
| + }
|
| + _onClosed = callback;
|
| + }
|
| +
|
| + void set _onClosed(void callback()) {
|
| _socketCloseHandler = callback;
|
| }
|
|
|
| void set onConnect(void callback()) {
|
| + if (_outputStream != null) {
|
| + throw new StreamException(
|
| + "Cannot set connect handler when output stream is used");
|
| + }
|
| + if (_status == CONNECTED || _status == CLOSED) {
|
| + throw new StreamException(
|
| + "Cannot set connect handler when already connected");
|
| + }
|
| + _onConnect = callback;
|
| + }
|
| +
|
| + void set _onConnect(void callback()) {
|
| _socketConnectHandler = callback;
|
| }
|
|
|
| void set onData(void callback()) {
|
| + if (_outputStream != null) {
|
| + throw new StreamException(
|
| + "Cannot set data handler when input stream is used");
|
| + }
|
| + _onData = callback;
|
| + }
|
| +
|
| + void set _onData(void callback()) {
|
| _socketDataHandler = callback;
|
| }
|
|
|
| void set onWrite(void callback()) {
|
| + if (_outputStream != null) {
|
| + throw new StreamException(
|
| + "Cannot set write handler when output stream is used");
|
| + }
|
| + _onWrite = callback;
|
| + }
|
| +
|
| + void set _onWrite(void callback()) {
|
| _socketWriteHandler = callback;
|
| // Reset the one-shot onWrite handler.
|
| _socket.onWrite = _tlsWriteHandler;
|
| }
|
|
|
| + InputStream get inputStream {
|
| + if (_inputStream == null) {
|
| + if (_socketDataHandler != null || _socketCloseHandler != null) {
|
| + throw new StreamException(
|
| + "Cannot get input stream when socket handlers are used");
|
| + }
|
| + _inputStream = new _SocketInputStream(this);
|
| + }
|
| + return _inputStream;
|
| + }
|
| +
|
| OutputStream get outputStream {
|
| - // TODO(6701): Implement stream interfaces on TlsSocket.
|
| - throw new UnimplementedError("TlsSocket.inputStream not implemented yet");
|
| + if (_outputStream == null) {
|
| + if (_socketConnectHandler != null || _socketWriteHandler != null) {
|
| + throw new StreamException(
|
| + "Cannot get output stream when socket handlers are used");
|
| + }
|
| + _outputStream = new _SocketOutputStream(this);
|
| + }
|
| + return _outputStream;
|
| }
|
|
|
| int available() {
|
| @@ -143,10 +191,15 @@ class _TlsSocket implements TlsSocket {
|
| }
|
| }
|
|
|
| + void _closeWrite() => close(true);
|
| +
|
| List<int> read([int len]) {
|
| if (_closedRead) {
|
| throw new SocketException("Reading from a closed socket");
|
| }
|
| + if (_status != CONNECTED) {
|
| + return new List<int>(0);
|
| + }
|
| var buffer = _tlsFilter.buffers[READ_PLAINTEXT];
|
| _readEncryptedData();
|
| int toRead = buffer.length;
|
| @@ -173,6 +226,9 @@ class _TlsSocket implements TlsSocket {
|
| throw new ArgumentError(
|
| "Invalid offset or bytes in TlsSocket.readList");
|
| }
|
| + if (_status != CONNECTED && _status != CLOSED) {
|
| + return 0;
|
| + }
|
|
|
| int bytesRead = 0;
|
| var buffer = _tlsFilter.buffers[READ_PLAINTEXT];
|
| @@ -200,6 +256,7 @@ class _TlsSocket implements TlsSocket {
|
| if (_closedWrite) {
|
| throw new SocketException("Writing to a closed socket");
|
| }
|
| + if (_status != CONNECTED) return 0;
|
| var buffer = _tlsFilter.buffers[WRITE_PLAINTEXT];
|
| if (bytes > buffer.free) {
|
| bytes = buffer.free;
|
| @@ -285,8 +342,15 @@ class _TlsSocket implements TlsSocket {
|
| _connectPending = false;
|
| _socketConnectHandler();
|
| }
|
| + if (_socketWriteHandler != null) {
|
| + _socket.onWrite = _tlsWriteHandler;
|
| + }
|
| }
|
|
|
| + // True if the underlying socket is closed, the filter has been emptied of
|
| + // all data, and the close event has been fired.
|
| + get _closed => _socketClosed && !_fireCloseEventPending;
|
| +
|
| void _fireCloseEvent() {
|
| if (scheduledDataEvent != null) {
|
| scheduledDataEvent.cancel();
|
| @@ -408,6 +472,8 @@ class _TlsSocket implements TlsSocket {
|
| }
|
| }
|
|
|
| + bool get _socketClosed => _closedRead;
|
| +
|
| // _TlsSocket cannot extend _Socket and use _Socket's factory constructor.
|
| Socket _socket;
|
| String _host;
|
| @@ -422,6 +488,8 @@ class _TlsSocket implements TlsSocket {
|
| bool _closedWrite = false; // The secure socket has been closed for writing.
|
| bool _filterReadEmpty = true; // There is no buffered data to read.
|
| bool _filterWriteEmpty = true; // There is no buffered data to be written.
|
| + _SocketInputStream _inputStream;
|
| + _SocketOutputStream _outputStream;
|
| bool _connectPending = false;
|
| Function _socketConnectHandler;
|
| Function _socketWriteHandler;
|
|
|