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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sdk/lib/io/process.dart ('k') | sdk/lib/io/secure_socket.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of dart.io; 5 part of dart.io;
6 6
7 abstract class SecureServerSocket implements ServerSocket { 7 /**
8 /** 8 * The [SecureServerSocket] is a server socket, providing a stream of high-level
9 * Constructs a new secure server socket, binds it to a given address 9 * [Socket]s.
10 * and port, and listens on it. Incoming client connections are 10 *
11 * promoted to secure connections, using the server certificate given by 11 * See [SecureSocket] for more info.
12 * certificate_name. The bindAddress must be given as a numeric address, 12 */
13 * not a host name. The certificate name is the distinguished name (DN) of 13 class SecureServerSocket extends Stream<SecureSocket> implements ServerSocket {
14 * the certificate, such as "CN=localhost" or "CN=myserver.mydomain.com". 14 final RawSecureServerSocket _socket;
15 * The certificate is looked up in the NSS certificate database set by 15
16 * SecureSocket.setCertificateDatabase. 16 SecureServerSocket._(RawSecureServerSocket this._socket);
17
18 /**
19 * Returns a future for a [SecureServerSocket]. When the future
20 * completes the server socket is bound to the given [address] and
21 * [port] and has started listening on it.
22 *
23 * If [port] has the value [:0:] (the default) an ephemeral port will
24 * be chosen by the system. The actual port used can be retrieved
25 * using the [port] getter.
26 *
27 * If [backlog] has the value of [:0:] a reasonable value will be
28 * chosen by the system.
29 *
30 * Incoming client connections are promoted to secure connections, using
31 * the server certificate given by [certificateName].
32 *
33 * [address] must be given as a numeric address, not a host name.
34 *
35 * [certificateName] is the nickname or the distinguished name (DN) of
36 * the certificate in the certificate database. It is looked up in the
37 * NSS certificate database set by SecureSocket.setCertificateDatabase.
38 * If [certificateName] contains "CN=", it is assumed to be a distinguished
39 * name. Otherwise, it is looked up as a nickname.
40 *
41 * To request or require that clients authenticate by providing an SSL (TLS)
42 * client certificate, set the optional parameter [requestClientCertificate]
43 * or [requireClientCertificate] to true. Requiring a certificate implies
44 * requesting a certificate, so one doesn't need to set both to true.
45 * To check whether a client certificate was received, check
46 * SecureSocket.peerCertificate after connecting. If no certificate
47 * was received, the result will be null.
48 */
49 static Future<SecureServerSocket> bind(
50 String address,
51 int port,
52 int backlog,
53 String certificateName,
54 {bool requestClientCertificate: false,
55 bool requireClientCertificate: false}) {
56 return RawSecureServerSocket.bind(
57 address,
58 port,
59 backlog,
60 certificateName,
61 requestClientCertificate: requestClientCertificate,
62 requireClientCertificate: requireClientCertificate).then(
63 (serverSocket) => new SecureServerSocket._(serverSocket));
64 }
65
66 StreamSubscription<SecureSocket> listen(void onData(SecureSocket socket),
67 {void onError(AsyncError error),
68 void onDone(),
69 bool unsubscribeOnError}) {
70 return _socket.map((rawSocket) => new SecureSocket._(rawSocket))
71 .listen(onData,
72 onError: onError,
73 onDone: onDone,
74 unsubscribeOnError: unsubscribeOnError);
75 }
76
77 /**
78 * Returns the port used by this socket.
79 */
80 int get port => _socket.port;
81
82 /**
83 * Closes the socket.
84 */
85 void close() => _socket.close();
86 }
87
88
89 /**
90 * The RawSecureServerSocket is a server socket, providing a stream of low-level
91 * [RawSecureSocket]s.
92 *
93 * See [RawSecureSocket] for more info.
94 */
95 class RawSecureServerSocket extends Stream<RawSecureSocket> {
96 RawServerSocket _socket;
97 StreamController<RawSecureSocket> _controller;
98 StreamSubscription<RawSocket> _subscription;
99 final String certificateName;
100 final bool requestClientCertificate;
101 final bool requireClientCertificate;
102 bool _closed = false;
103
104 RawSecureServerSocket._(RawServerSocket serverSocket,
105 String this.certificateName,
106 bool this.requestClientCertificate,
107 bool this.requireClientCertificate) {
108 _socket = serverSocket;
109 _controller = new StreamController<RawSecureSocket>(
110 onPauseStateChange: _onPauseStateChange,
111 onSubscriptionStateChange: _onSubscriptionStateChange);
112 }
113
114 /**
115 * Returns a future for a [RawSecureServerSocket]. When the future
116 * completes the server socket is bound to the given [address] and
117 * [port] and has started listening on it.
118 *
119 * If [port] has the value [:0:] (the default) an ephemeral port will
120 * be chosen by the system. The actual port used can be retrieved
121 * using the [port] getter.
122 *
123 * If [backlog] has the value of [:0:] a reasonable value will be
124 * chosen by the system.
125 *
126 * Incoming client connections are promoted to secure connections,
127 * using the server certificate given by [certificateName].
128 *
129 * [address] must be given as a numeric address, not a host name.
130 *
131 * [certificateName] is the nickname or the distinguished name (DN) of
132 * the certificate in the certificate database. It is looked up in the
133 * NSS certificate database set by SecureSocket.setCertificateDatabase.
134 * If [certificateName] contains "CN=", it is assumed to be a distinguished
135 * name. Otherwise, it is looked up as a nickname.
17 * 136 *
18 * To request or require that clients authenticate by providing an SSL (TLS) 137 * To request or require that clients authenticate by providing an SSL (TLS)
19 * client certificate, set the optional parameters requestClientCertificate or 138 * client certificate, set the optional parameters requestClientCertificate or
20 * requireClientCertificate to true. Require implies request, so one doesn't 139 * requireClientCertificate to true. Require implies request, so one doesn't
21 * need to specify both. To check whether a client certificate was received, 140 * need to specify both. To check whether a client certificate was received,
22 * check SecureSocket.peerCertificate after connecting. If no certificate 141 * check SecureSocket.peerCertificate after connecting. If no certificate
23 * was received, the result will be null. 142 * was received, the result will be null.
24 */ 143 */
25 factory SecureServerSocket(String bindAddress, 144 static Future<RawSecureServerSocket> bind(
26 int port, 145 String address,
27 int backlog, 146 int port,
28 String certificate_name, 147 int backlog,
29 {bool requestClientCertificate: false, 148 String certificateName,
30 bool requireClientCertificate: false}) { 149 {bool requestClientCertificate: false,
31 return new _SecureServerSocket(bindAddress, 150 bool requireClientCertificate: false}) {
32 port, 151 return RawServerSocket.bind(address, port, backlog)
33 backlog, 152 .then((serverSocket) => new RawSecureServerSocket._(
34 certificate_name, 153 serverSocket,
35 requestClientCertificate, 154 certificateName,
36 requireClientCertificate); 155 requestClientCertificate,
37 } 156 requireClientCertificate));
38 } 157 }
39 158
40 159 StreamSubscription<RawSecureSocket> listen(void onData(RawSecureSocket s),
41 class _SecureServerSocket implements SecureServerSocket { 160 {void onError(AsyncError error),
42 161 void onDone(),
43 _SecureServerSocket(String bindAddress, 162 bool unsubscribeOnError}) {
44 int port, 163 return _controller.stream.listen(onData,
45 int backlog, 164 onError: onError,
46 String this.certificate_name, 165 onDone: onDone,
47 bool this.requestClientCertificate, 166 unsubscribeOnError: unsubscribeOnError);
48 bool this.requireClientCertificate) {
49 socket = new ServerSocket(bindAddress, port, backlog);
50 socket.onConnection = this._onConnectionHandler;
51 }
52
53 void set onConnection(void callback(Socket connection)) {
54 _onConnectionCallback = callback;
55 }
56
57 void set onError(void callback(e)) {
58 socket.onError = callback;
59 } 167 }
60 168
61 /** 169 /**
62 * Returns the port used by this socket. 170 * Returns the port used by this socket.
63 */ 171 */
64 int get port => socket.port; 172 int get port => _socket.port;
65 173
66 /** 174 /**
67 * Closes the socket. 175 * Closes the socket.
68 */ 176 */
69 void close() { 177 void close() {
70 socket.close(); 178 _closed = true;
71 } 179 _socket.close();
72 180 }
73 void _onConnectionHandler(Socket connection) { 181
74 if (_onConnectionCallback == null) { 182 void _onData(RawSocket connection) {
75 connection.close(); 183 _RawSecureSocket.connect(
76 throw new SocketIOException(
77 "SecureServerSocket with no onConnection callback connected to");
78 }
79 if (certificate_name == null) {
80 connection.close();
81 throw new SocketIOException(
82 "SecureServerSocket with server certificate not set connected to");
83 }
84 var secure_connection = new _SecureSocket(
85 connection.remoteHost, 184 connection.remoteHost,
86 connection.remotePort, 185 connection.remotePort,
87 certificate_name, 186 certificateName,
88 is_server: true, 187 is_server: true,
89 socket: connection, 188 socket: connection,
90 requestClientCertificate: requestClientCertificate, 189 requestClientCertificate: requestClientCertificate,
91 requireClientCertificate: requireClientCertificate); 190 requireClientCertificate: requireClientCertificate)
92 _onConnectionCallback(secure_connection); 191 .then((RawSecureSocket secureConnection) {
93 } 192 if (_closed) {
94 193 secureConnection.close();
95 ServerSocket socket; 194 } else {
96 var _onConnectionCallback; 195 _controller.add(secureConnection);
97 final String certificate_name; 196 }
98 final bool requestClientCertificate; 197 }).catchError((e) {
99 final bool requireClientCertificate; 198 if (_closed) {
199 throw e;
200 } else {
201 _controller.signalError(e);
202 close();
203 }
204 });
205 }
206
207 void _onError(e) {
208 _controller.signalError(e);
209 close();
210 }
211
212 void _onDone() {
213 _controller.close();
214 }
215
216 void _onPauseStateChange() {
217 if (_controller.isPaused) {
218 _subscription.pause();
219 } else {
220 _subscription.resume();
221 }
222 }
223
224 void _onSubscriptionStateChange() {
225 if (_controller.hasSubscribers) {
226 _subscription = _socket.listen(_onData,
227 onDone: _onDone,
228 onError: _onError);
229 } else {
230 close();
231 }
232 }
100 } 233 }
234
235
OLDNEW
« 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