| // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 | // | 
 | // This test tests TLS session resume, by making multiple client connections | 
 | // on the same port to the same server, with a delay of 200 ms between them. | 
 | // The unmodified secure_server_test creates all sessions simultaneously, | 
 | // which means that no handshake completes and caches its keys in the session | 
 | // cache in time for other connections to use it. | 
 | // | 
 | // Session resume is currently disabled - see issue | 
 | // https://code.google.com/p/dart/issues/detail?id=7230 | 
 | // | 
 | // VMOptions= | 
 | // VMOptions=--short_socket_read | 
 | // VMOptions=--short_socket_write | 
 | // VMOptions=--short_socket_read --short_socket_write | 
 | // OtherResources=certificates/server_chain.pem | 
 | // OtherResources=certificates/server_key.pem | 
 | // OtherResources=certificates/trusted_certs.pem | 
 |  | 
 | import "dart:async"; | 
 | import "dart:io"; | 
 | import "dart:isolate"; | 
 |  | 
 | import "package:expect/expect.dart"; | 
 | import "package:async_helper/async_helper.dart"; | 
 |  | 
 | late InternetAddress HOST; | 
 |  | 
 | String localFile(path) => Platform.script.resolve(path).toFilePath(); | 
 |  | 
 | SecurityContext serverContext = new SecurityContext() | 
 |   ..useCertificateChain(localFile('certificates/server_chain.pem')) | 
 |   ..usePrivateKey(localFile('certificates/server_key.pem'), | 
 |       password: 'dartdart'); | 
 |  | 
 | SecurityContext clientContext = new SecurityContext() | 
 |   ..setTrustedCertificates(localFile('certificates/trusted_certs.pem')); | 
 |  | 
 | Future<SecureServerSocket> startServer() { | 
 |   return SecureServerSocket.bind(HOST, 0, serverContext).then((server) { | 
 |     server.listen((SecureSocket client) { | 
 |       client.fold<List<int>>( | 
 |           <int>[], (message, data) => message..addAll(data)).then((message) { | 
 |         String received = new String.fromCharCodes(message); | 
 |         Expect.isTrue(received.contains("Hello from client ")); | 
 |         String name = received.substring(received.indexOf("client ") + 7); | 
 |         client.write("Welcome, client $name"); | 
 |         client.close(); | 
 |       }); | 
 |     }); | 
 |     return server; | 
 |   }); | 
 | } | 
 |  | 
 | Future testClient(server, name) { | 
 |   return SecureSocket.connect(HOST, server.port, context: clientContext) | 
 |       .then((socket) { | 
 |     socket.write("Hello from client $name"); | 
 |     socket.close(); | 
 |     return socket.fold<List<int>>( | 
 |         <int>[], (message, data) => message..addAll(data)).then((message) { | 
 |       Expect.listEquals("Welcome, client $name".codeUnits, message); | 
 |       return server; | 
 |     }); | 
 |   }); | 
 | } | 
 |  | 
 | void main() { | 
 |   asyncStart(); | 
 |   InternetAddress.lookup("localhost").then((hosts) { | 
 |     HOST = hosts.first; | 
 |     runTests().then((_) => asyncEnd()); | 
 |   }); | 
 | } | 
 |  | 
 | Future runTests() { | 
 |   Duration delay = const Duration(milliseconds: 0); | 
 |   Duration delay_between_connections = const Duration(milliseconds: 300); | 
 |   return startServer() | 
 |       .then((server) => Future.wait( | 
 |               ['able', 'baker', 'charlie', 'dozen', 'elapse'].map((name) { | 
 |             delay += delay_between_connections; | 
 |             return new Future.delayed(delay, () => server) | 
 |                 .then((server) => testClient(server, name)); | 
 |           }))) | 
 |       .then((servers) => servers.first.close()); | 
 | } |