Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: sdk/lib/io/secure_server_socket.dart

Issue 12316036: Merge IO v2 branch to bleeding edge (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased to r18818 Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/io/process.dart ('k') | sdk/lib/io/secure_socket.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/secure_server_socket.dart
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index 7c8d78f98800e57bb0a6e1830dba43e345612311..7a9b34d7c203a0088b3923b29556bd8c9b8f847a 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -4,97 +4,232 @@
part of dart.io;
-abstract class SecureServerSocket implements ServerSocket {
+/**
+ * The [SecureServerSocket] is a server socket, providing a stream of high-level
+ * [Socket]s.
+ *
+ * See [SecureSocket] for more info.
+ */
+class SecureServerSocket extends Stream<SecureSocket> implements ServerSocket {
+ final RawSecureServerSocket _socket;
+
+ SecureServerSocket._(RawSecureServerSocket this._socket);
+
/**
- * Constructs a new secure server socket, binds it to a given address
- * and port, and listens on it. Incoming client connections are
- * promoted to secure connections, using the server certificate given by
- * certificate_name. The bindAddress must be given as a numeric address,
- * not a host name. The certificate name is the distinguished name (DN) of
- * the certificate, such as "CN=localhost" or "CN=myserver.mydomain.com".
- * The certificate is looked up in the NSS certificate database set by
- * SecureSocket.setCertificateDatabase.
+ * Returns a future for a [SecureServerSocket]. When the future
+ * completes the server socket is bound to the given [address] and
+ * [port] and has started listening on it.
+ *
+ * If [port] has the value [:0:] (the default) an ephemeral port will
+ * be chosen by the system. The actual port used can be retrieved
+ * using the [port] getter.
+ *
+ * If [backlog] has the value of [:0:] a reasonable value will be
+ * chosen by the system.
+ *
+ * Incoming client connections are promoted to secure connections, using
+ * the server certificate given by [certificateName].
+ *
+ * [address] must be given as a numeric address, not a host name.
+ *
+ * [certificateName] is the nickname or the distinguished name (DN) of
+ * the certificate in the certificate database. It is looked up in the
+ * NSS certificate database set by SecureSocket.setCertificateDatabase.
+ * If [certificateName] contains "CN=", it is assumed to be a distinguished
+ * name. Otherwise, it is looked up as a nickname.
*
* To request or require that clients authenticate by providing an SSL (TLS)
- * client certificate, set the optional parameters requestClientCertificate or
- * requireClientCertificate to true. Require implies request, so one doesn't
- * need to specify both. To check whether a client certificate was received,
- * check SecureSocket.peerCertificate after connecting. If no certificate
+ * client certificate, set the optional parameter [requestClientCertificate]
+ * or [requireClientCertificate] to true. Requiring a certificate implies
+ * requesting a certificate, so one doesn't need to set both to true.
+ * To check whether a client certificate was received, check
+ * SecureSocket.peerCertificate after connecting. If no certificate
* was received, the result will be null.
*/
- factory SecureServerSocket(String bindAddress,
- int port,
- int backlog,
- String certificate_name,
- {bool requestClientCertificate: false,
- bool requireClientCertificate: false}) {
- return new _SecureServerSocket(bindAddress,
- port,
- backlog,
- certificate_name,
- requestClientCertificate,
- requireClientCertificate);
+ static Future<SecureServerSocket> bind(
+ String address,
+ int port,
+ int backlog,
+ String certificateName,
+ {bool requestClientCertificate: false,
+ bool requireClientCertificate: false}) {
+ return RawSecureServerSocket.bind(
+ address,
+ port,
+ backlog,
+ certificateName,
+ requestClientCertificate: requestClientCertificate,
+ requireClientCertificate: requireClientCertificate).then(
+ (serverSocket) => new SecureServerSocket._(serverSocket));
+ }
+
+ StreamSubscription<SecureSocket> listen(void onData(SecureSocket socket),
+ {void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError}) {
+ return _socket.map((rawSocket) => new SecureSocket._(rawSocket))
+ .listen(onData,
+ onError: onError,
+ onDone: onDone,
+ unsubscribeOnError: unsubscribeOnError);
}
+
+ /**
+ * Returns the port used by this socket.
+ */
+ int get port => _socket.port;
+
+ /**
+ * Closes the socket.
+ */
+ void close() => _socket.close();
}
-class _SecureServerSocket implements SecureServerSocket {
+/**
+ * The RawSecureServerSocket is a server socket, providing a stream of low-level
+ * [RawSecureSocket]s.
+ *
+ * See [RawSecureSocket] for more info.
+ */
+class RawSecureServerSocket extends Stream<RawSecureSocket> {
+ RawServerSocket _socket;
+ StreamController<RawSecureSocket> _controller;
+ StreamSubscription<RawSocket> _subscription;
+ final String certificateName;
+ final bool requestClientCertificate;
+ final bool requireClientCertificate;
+ bool _closed = false;
- _SecureServerSocket(String bindAddress,
- int port,
- int backlog,
- String this.certificate_name,
- bool this.requestClientCertificate,
- bool this.requireClientCertificate) {
- socket = new ServerSocket(bindAddress, port, backlog);
- socket.onConnection = this._onConnectionHandler;
+ RawSecureServerSocket._(RawServerSocket serverSocket,
+ String this.certificateName,
+ bool this.requestClientCertificate,
+ bool this.requireClientCertificate) {
+ _socket = serverSocket;
+ _controller = new StreamController<RawSecureSocket>(
+ onPauseStateChange: _onPauseStateChange,
+ onSubscriptionStateChange: _onSubscriptionStateChange);
}
- void set onConnection(void callback(Socket connection)) {
- _onConnectionCallback = callback;
+ /**
+ * Returns a future for a [RawSecureServerSocket]. When the future
+ * completes the server socket is bound to the given [address] and
+ * [port] and has started listening on it.
+ *
+ * If [port] has the value [:0:] (the default) an ephemeral port will
+ * be chosen by the system. The actual port used can be retrieved
+ * using the [port] getter.
+ *
+ * If [backlog] has the value of [:0:] a reasonable value will be
+ * chosen by the system.
+ *
+ * Incoming client connections are promoted to secure connections,
+ * using the server certificate given by [certificateName].
+ *
+ * [address] must be given as a numeric address, not a host name.
+ *
+ * [certificateName] is the nickname or the distinguished name (DN) of
+ * the certificate in the certificate database. It is looked up in the
+ * NSS certificate database set by SecureSocket.setCertificateDatabase.
+ * If [certificateName] contains "CN=", it is assumed to be a distinguished
+ * name. Otherwise, it is looked up as a nickname.
+ *
+ * To request or require that clients authenticate by providing an SSL (TLS)
+ * client certificate, set the optional parameters requestClientCertificate or
+ * requireClientCertificate to true. Require implies request, so one doesn't
+ * need to specify both. To check whether a client certificate was received,
+ * check SecureSocket.peerCertificate after connecting. If no certificate
+ * was received, the result will be null.
+ */
+ static Future<RawSecureServerSocket> bind(
+ String address,
+ int port,
+ int backlog,
+ String certificateName,
+ {bool requestClientCertificate: false,
+ bool requireClientCertificate: false}) {
+ return RawServerSocket.bind(address, port, backlog)
+ .then((serverSocket) => new RawSecureServerSocket._(
+ serverSocket,
+ certificateName,
+ requestClientCertificate,
+ requireClientCertificate));
}
- void set onError(void callback(e)) {
- socket.onError = callback;
+ StreamSubscription<RawSecureSocket> listen(void onData(RawSecureSocket s),
+ {void onError(AsyncError error),
+ void onDone(),
+ bool unsubscribeOnError}) {
+ return _controller.stream.listen(onData,
+ onError: onError,
+ onDone: onDone,
+ unsubscribeOnError: unsubscribeOnError);
}
/**
* Returns the port used by this socket.
*/
- int get port => socket.port;
+ int get port => _socket.port;
/**
* Closes the socket.
*/
void close() {
- socket.close();
+ _closed = true;
+ _socket.close();
}
- void _onConnectionHandler(Socket connection) {
- if (_onConnectionCallback == null) {
- connection.close();
- throw new SocketIOException(
- "SecureServerSocket with no onConnection callback connected to");
- }
- if (certificate_name == null) {
- connection.close();
- throw new SocketIOException(
- "SecureServerSocket with server certificate not set connected to");
- }
- var secure_connection = new _SecureSocket(
+ void _onData(RawSocket connection) {
+ _RawSecureSocket.connect(
connection.remoteHost,
connection.remotePort,
- certificate_name,
+ certificateName,
is_server: true,
socket: connection,
requestClientCertificate: requestClientCertificate,
- requireClientCertificate: requireClientCertificate);
- _onConnectionCallback(secure_connection);
+ requireClientCertificate: requireClientCertificate)
+ .then((RawSecureSocket secureConnection) {
+ if (_closed) {
+ secureConnection.close();
+ } else {
+ _controller.add(secureConnection);
+ }
+ }).catchError((e) {
+ if (_closed) {
+ throw e;
+ } else {
+ _controller.signalError(e);
+ close();
+ }
+ });
}
- ServerSocket socket;
- var _onConnectionCallback;
- final String certificate_name;
- final bool requestClientCertificate;
- final bool requireClientCertificate;
+ void _onError(e) {
+ _controller.signalError(e);
+ close();
+ }
+
+ void _onDone() {
+ _controller.close();
+ }
+
+ void _onPauseStateChange() {
+ if (_controller.isPaused) {
+ _subscription.pause();
+ } else {
+ _subscription.resume();
+ }
+ }
+
+ void _onSubscriptionStateChange() {
+ if (_controller.hasSubscribers) {
+ _subscription = _socket.listen(_onData,
+ onDone: _onDone,
+ onError: _onError);
+ } else {
+ close();
+ }
+ }
}
+
+
« no previous file with comments | « sdk/lib/io/process.dart ('k') | sdk/lib/io/secure_socket.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698