| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of dart.io; | 5 part of dart.io; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A high-level class for communicating securely over a TCP socket, using | 8 * A high-level class for communicating securely over a TCP socket, using |
| 9 * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an | 9 * TLS and SSL. The [SecureSocket] exposes both a [Stream] and an |
| 10 * [IOSink] interface, making it ideal for using together with | 10 * [IOSink] interface, making it ideal for using together with |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 certificateName, | 276 certificateName, |
| 277 requestClientCertificate || | 277 requestClientCertificate || |
| 278 requireClientCertificate, | 278 requireClientCertificate, |
| 279 requireClientCertificate, | 279 requireClientCertificate, |
| 280 sendClientCertificate); | 280 sendClientCertificate); |
| 281 _status = HANDSHAKE; | 281 _status = HANDSHAKE; |
| 282 _secureHandshake(); | 282 _secureHandshake(); |
| 283 }) | 283 }) |
| 284 .catchError((error) { | 284 .catchError((error) { |
| 285 _handshakeComplete.completeError(error); | 285 _handshakeComplete.completeError(error); |
| 286 close(); | 286 _close(); |
| 287 }); | 287 }); |
| 288 } | 288 } |
| 289 | 289 |
| 290 StreamSubscription listen(void onData(RawSocketEvent data), | 290 StreamSubscription listen(void onData(RawSocketEvent data), |
| 291 {void onError(AsyncError error), | 291 {void onError(AsyncError error), |
| 292 void onDone(), | 292 void onDone(), |
| 293 bool unsubscribeOnError}) { | 293 bool unsubscribeOnError}) { |
| 294 if (_writeEventsEnabled) { | 294 if (_writeEventsEnabled) { |
| 295 _writeEventsEnabled = false; | 295 _writeEventsEnabled = false; |
| 296 _controller.add(RawSocketEvent.WRITE); | 296 _controller.add(RawSocketEvent.WRITE); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 | 334 |
| 335 int get remotePort => _socket.remotePort; | 335 int get remotePort => _socket.remotePort; |
| 336 | 336 |
| 337 int available() { | 337 int available() { |
| 338 if (_status != CONNECTED) return 0; | 338 if (_status != CONNECTED) return 0; |
| 339 _readEncryptedData(); | 339 _readEncryptedData(); |
| 340 return _secureFilter.buffers[READ_PLAINTEXT].length; | 340 return _secureFilter.buffers[READ_PLAINTEXT].length; |
| 341 } | 341 } |
| 342 | 342 |
| 343 void close() { | 343 void close() { |
| 344 shutdown(SocketDirection.BOTH); |
| 345 } |
| 346 |
| 347 void _close() { |
| 344 _closedWrite = true; | 348 _closedWrite = true; |
| 345 _closedRead = true; | 349 _closedRead = true; |
| 346 if (_socket != null) { | 350 if (_socket != null) { |
| 347 _socket.close(); | 351 _socket.close(); |
| 348 } | 352 } |
| 349 _socketClosedWrite = true; | 353 _socketClosedWrite = true; |
| 350 _socketClosedRead = true; | 354 _socketClosedRead = true; |
| 351 if (_secureFilter != null) { | 355 if (_secureFilter != null) { |
| 352 _secureFilter.destroy(); | 356 _secureFilter.destroy(); |
| 353 _secureFilter = null; | 357 _secureFilter = null; |
| 354 } | 358 } |
| 355 if (_socketSubscription != null) { | 359 if (_socketSubscription != null) { |
| 356 _socketSubscription.cancel(); | 360 _socketSubscription.cancel(); |
| 357 } | 361 } |
| 358 _controller.close(); | 362 _controller.close(); |
| 359 _status = CLOSED; | 363 _status = CLOSED; |
| 360 } | 364 } |
| 361 | 365 |
| 362 void shutdown(SocketDirection direction) { | 366 void shutdown(SocketDirection direction) { |
| 363 if (direction == SocketDirection.BOTH) { | 367 if (direction == SocketDirection.SEND || |
| 364 close(); | 368 direction == SocketDirection.BOTH) { |
| 365 } else if (direction == SocketDirection.SEND) { | |
| 366 _closedWrite = true; | 369 _closedWrite = true; |
| 367 _writeEncryptedData(); | 370 _writeEncryptedData(); |
| 368 if (_filterWriteEmpty) { | 371 if (_filterWriteEmpty) { |
| 369 _socket.shutdown(SocketDirection.SEND); | 372 _socket.shutdown(SocketDirection.SEND); |
| 370 _socketClosedWrite = true; | 373 _socketClosedWrite = true; |
| 371 if (_closedRead) { | 374 if (_closedRead) { |
| 372 close(); | 375 _close(); |
| 373 } | 376 } |
| 374 } | 377 } |
| 375 } else if (direction == SocketDirection.RECEIVE) { | 378 } |
| 379 if (direction == SocketDirection.RECEIVE || |
| 380 direction == SocketDirection.BOTH) { |
| 376 _closedRead = true; | 381 _closedRead = true; |
| 377 _socketClosedRead = true; | 382 _socketClosedRead = true; |
| 378 _socket.shutdown(SocketDirection.RECEIVE); | 383 _socket.shutdown(SocketDirection.RECEIVE); |
| 379 if (_socketClosedWrite) { | 384 if (_socketClosedWrite) { |
| 380 close(); | 385 _close(); |
| 381 } | 386 } |
| 382 } | 387 } |
| 383 } | 388 } |
| 384 | 389 |
| 385 bool get writeEventsEnabled => _writeEventsEnabled; | 390 bool get writeEventsEnabled => _writeEventsEnabled; |
| 386 | 391 |
| 387 void set writeEventsEnabled(bool value) { | 392 void set writeEventsEnabled(bool value) { |
| 388 if (value && | 393 if (value && |
| 389 _controller.hasSubscribers && | 394 _controller.hasSubscribers && |
| 390 _secureFilter != null && | 395 _secureFilter != null && |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 } | 541 } |
| 537 } | 542 } |
| 538 } else if (_socketClosedRead) { | 543 } else if (_socketClosedRead) { |
| 539 _closeHandler(); | 544 _closeHandler(); |
| 540 } | 545 } |
| 541 } | 546 } |
| 542 } | 547 } |
| 543 | 548 |
| 544 void _doneHandler() { | 549 void _doneHandler() { |
| 545 if (_filterReadEmpty) { | 550 if (_filterReadEmpty) { |
| 546 close(); | 551 _close(); |
| 547 } | 552 } |
| 548 } | 553 } |
| 549 | 554 |
| 550 void _errorHandler(e) { | 555 void _errorHandler(e) { |
| 551 _reportError(e, 'Error on underlying RawSocket'); | 556 _reportError(e, 'Error on underlying RawSocket'); |
| 552 } | 557 } |
| 553 | 558 |
| 554 void _reportError(error, String message) { | 559 void _reportError(error, String message) { |
| 555 // TODO(whesse): Call _reportError from all internal functions that throw. | 560 // TODO(whesse): Call _reportError from all internal functions that throw. |
| 556 var e; | 561 var e; |
| 557 if (error is AsyncError) { | 562 if (error is AsyncError) { |
| 558 e = error; | 563 e = error; |
| 559 } else if (error is SocketIOException) { | 564 } else if (error is SocketIOException) { |
| 560 e = new SocketIOException('$message (${error.message})', error.osError); | 565 e = new SocketIOException('$message (${error.message})', error.osError); |
| 561 } else if (error is OSError) { | 566 } else if (error is OSError) { |
| 562 e = new SocketIOException(message, error); | 567 e = new SocketIOException(message, error); |
| 563 } else { | 568 } else { |
| 564 e = new SocketIOException('$message (${error.toString()})', null); | 569 e = new SocketIOException('$message (${error.toString()})', null); |
| 565 } | 570 } |
| 566 if (_connectPending) { | 571 if (_connectPending) { |
| 567 _handshakeComplete.completeError(e); | 572 _handshakeComplete.completeError(e); |
| 568 } else { | 573 } else { |
| 569 _controller.signalError(e); | 574 _controller.signalError(e); |
| 570 } | 575 } |
| 571 close(); | 576 _close(); |
| 572 } | 577 } |
| 573 | 578 |
| 574 void _closeHandler() { | 579 void _closeHandler() { |
| 575 if (_status == CONNECTED) { | 580 if (_status == CONNECTED) { |
| 576 if (_closedRead) return; | 581 if (_closedRead) return; |
| 577 _socketClosedRead = true; | 582 _socketClosedRead = true; |
| 578 if (_filterReadEmpty) { | 583 if (_filterReadEmpty) { |
| 579 _closedRead = true; | 584 _closedRead = true; |
| 580 _controller.add(RawSocketEvent.READ_CLOSED); | 585 _controller.add(RawSocketEvent.READ_CLOSED); |
| 581 if (_socketClosedWrite) { | 586 if (_socketClosedWrite) { |
| 582 close(); | 587 _close(); |
| 583 } | 588 } |
| 584 } | 589 } |
| 585 } else if (_status == HANDSHAKE) { | 590 } else if (_status == HANDSHAKE) { |
| 586 _reportError( | 591 _reportError( |
| 587 new SocketIOException('Connection terminated during handshake'), | 592 new SocketIOException('Connection terminated during handshake'), |
| 588 'handshake error'); | 593 'handshake error'); |
| 589 } | 594 } |
| 590 } | 595 } |
| 591 | 596 |
| 592 void _secureHandshake() { | 597 void _secureHandshake() { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 void destroy(); | 747 void destroy(); |
| 743 void handshake(); | 748 void handshake(); |
| 744 void init(); | 749 void init(); |
| 745 X509Certificate get peerCertificate; | 750 X509Certificate get peerCertificate; |
| 746 int processBuffer(int bufferIndex); | 751 int processBuffer(int bufferIndex); |
| 747 void registerBadCertificateCallback(Function callback); | 752 void registerBadCertificateCallback(Function callback); |
| 748 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); | 753 void registerHandshakeCompleteCallback(Function handshakeCompleteHandler); |
| 749 | 754 |
| 750 List<_ExternalBuffer> get buffers; | 755 List<_ExternalBuffer> get buffers; |
| 751 } | 756 } |
| OLD | NEW |