OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library test.runner.browser.server; | 5 library test.runner.browser.server; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 import 'dart:io'; | 9 import 'dart:io'; |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 /// A server that serves JS-compiled tests to browsers. | 34 /// A server that serves JS-compiled tests to browsers. |
35 /// | 35 /// |
36 /// A test suite may be loaded for a given file using [loadSuite]. | 36 /// A test suite may be loaded for a given file using [loadSuite]. |
37 class BrowserServer { | 37 class BrowserServer { |
38 /// Starts the server. | 38 /// Starts the server. |
39 /// | 39 /// |
40 /// [root] is the root directory that the server should serve. It defaults to | 40 /// [root] is the root directory that the server should serve. It defaults to |
41 /// the working directory. | 41 /// the working directory. |
42 static Future<BrowserServer> start(Configuration config, {String root}) | 42 static Future<BrowserServer> start(Configuration config, {String root}) |
43 async { | 43 async { |
44 var server = new BrowserServer._(root, config); | 44 var server = new shelf_io.IOServer(await HttpMultiServer.loopback(0)); |
45 await server._load(); | 45 return new BrowserServer(server, config, root: root); |
46 return server; | |
47 } | 46 } |
48 | 47 |
49 /// The underlying HTTP server. | 48 /// The underlying server. |
50 HttpServer _server; | 49 final shelf.Server _server; |
51 | 50 |
52 /// A randomly-generated secret. | 51 /// A randomly-generated secret. |
53 /// | 52 /// |
54 /// This is used to ensure that other users on the same system can't snoop | 53 /// This is used to ensure that other users on the same system can't snoop |
55 /// on data being served through this server. | 54 /// on data being served through this server. |
56 final _secret = randomBase64(24, urlSafe: true); | 55 final _secret = randomBase64(24, urlSafe: true); |
57 | 56 |
58 /// The URL for this server. | 57 /// The URL for this server. |
59 Uri get url => baseUrlForAddress(_server.address, _server.port) | 58 Uri get url => _server.url.resolve(_secret + "/"); |
60 .resolve(_secret + "/"); | |
61 | 59 |
62 /// The test runner configuration. | 60 /// The test runner configuration. |
63 Configuration _config; | 61 Configuration _config; |
64 | 62 |
65 /// A [OneOffHandler] for servicing WebSocket connections for | 63 /// A [OneOffHandler] for servicing WebSocket connections for |
66 /// [BrowserManager]s. | 64 /// [BrowserManager]s. |
67 /// | 65 /// |
68 /// This is one-off because each [BrowserManager] can only connect to a single | 66 /// This is one-off because each [BrowserManager] can only connect to a single |
69 /// WebSocket, | 67 /// WebSocket, |
70 final _webSocketHandler = new OneOffHandler(); | 68 final _webSocketHandler = new OneOffHandler(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 | 106 |
109 /// A map from test suite paths to Futures that will complete once those | 107 /// A map from test suite paths to Futures that will complete once those |
110 /// suites are finished compiling. | 108 /// suites are finished compiling. |
111 /// | 109 /// |
112 /// This is used to make sure that a given test suite is only compiled once | 110 /// This is used to make sure that a given test suite is only compiled once |
113 /// per run, rather than once per browser per run. | 111 /// per run, rather than once per browser per run. |
114 final _compileFutures = new Map<String, Future>(); | 112 final _compileFutures = new Map<String, Future>(); |
115 | 113 |
116 final _mappers = new Map<String, StackTraceMapper>(); | 114 final _mappers = new Map<String, StackTraceMapper>(); |
117 | 115 |
118 BrowserServer._(String root, Configuration config) | 116 BrowserServer(this._server, Configuration config, {String root}) |
119 : _root = root == null ? p.current : root, | 117 : _root = root == null ? p.current : root, |
120 _config = config, | 118 _config = config, |
121 _compiledDir = config.pubServeUrl == null ? createTempDir() : null, | 119 _compiledDir = config.pubServeUrl == null ? createTempDir() : null, |
122 _http = config.pubServeUrl == null ? null : new HttpClient(), | 120 _http = config.pubServeUrl == null ? null : new HttpClient(), |
123 _compilers = new CompilerPool(color: config.color); | 121 _compilers = new CompilerPool(color: config.color) { |
124 | |
125 /// Starts the underlying server. | |
126 Future _load() async { | |
127 var cascade = new shelf.Cascade() | 122 var cascade = new shelf.Cascade() |
128 .add(_webSocketHandler.handler); | 123 .add(_webSocketHandler.handler); |
129 | 124 |
130 if (_config.pubServeUrl == null) { | 125 if (_config.pubServeUrl == null) { |
131 cascade = cascade | 126 cascade = cascade |
132 .add(_createPackagesHandler()) | 127 .add(_createPackagesHandler()) |
133 .add(_jsHandler.handler) | 128 .add(_jsHandler.handler) |
134 .add(createStaticHandler(_root)) | 129 .add(createStaticHandler(_root)) |
135 .add(_wrapperHandler); | 130 .add(_wrapperHandler); |
136 } | 131 } |
137 | 132 |
138 var pipeline = new shelf.Pipeline() | 133 var pipeline = new shelf.Pipeline() |
139 .addMiddleware(nestingMiddleware(_secret)) | 134 .addMiddleware(nestingMiddleware(_secret)) |
140 .addHandler(cascade.handler); | 135 .addHandler(cascade.handler); |
141 | 136 |
142 _server = await HttpMultiServer.loopback(0); | 137 _server.mount(pipeline); |
143 shelf_io.serveRequests(_server, pipeline); | |
144 } | 138 } |
145 | 139 |
146 /// Returns a handler that serves the contents of the "packages/" directory | 140 /// Returns a handler that serves the contents of the "packages/" directory |
147 /// for any URL that contains "packages/". | 141 /// for any URL that contains "packages/". |
148 /// | 142 /// |
149 /// This is a factory so it can wrap a static handler. | 143 /// This is a factory so it can wrap a static handler. |
150 shelf.Handler _createPackagesHandler() { | 144 shelf.Handler _createPackagesHandler() { |
151 var staticHandler = | 145 var staticHandler = |
152 createStaticHandler(_config.packageRoot, serveFilesOutsidePath: true); | 146 createStaticHandler(_config.packageRoot, serveFilesOutsidePath: true); |
153 | 147 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 await Future.wait(futures); | 406 await Future.wait(futures); |
413 | 407 |
414 if (_config.pubServeUrl == null) { | 408 if (_config.pubServeUrl == null) { |
415 new Directory(_compiledDir).deleteSync(recursive: true); | 409 new Directory(_compiledDir).deleteSync(recursive: true); |
416 } else { | 410 } else { |
417 _http.close(); | 411 _http.close(); |
418 } | 412 } |
419 }); | 413 }); |
420 } | 414 } |
421 } | 415 } |
OLD | NEW |