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

Side by Side Diff: tools/testing/dart/http_server.dart

Issue 2997753002: Revert "Remove support for "packages" URL from testing server." (Closed)
Patch Set: Created 3 years, 4 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
« no previous file with comments | « tools/testing/dart/configuration.dart ('k') | no next file » | 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) 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 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:convert' show HtmlEscape; 6 import 'dart:convert' show HtmlEscape;
7 import 'dart:io'; 7 import 'dart:io';
8 8
9 import 'package:package_resolver/package_resolver.dart';
10
9 import 'configuration.dart'; 11 import 'configuration.dart';
10 import 'vendored_pkg/args/args.dart'; 12 import 'vendored_pkg/args/args.dart';
11 import 'utils.dart'; 13 import 'utils.dart';
12 14
13 class DispatchingServer { 15 class DispatchingServer {
14 HttpServer server; 16 HttpServer server;
15 Map<String, Function> _handlers = new Map<String, Function>(); 17 Map<String, Function> _handlers = new Map<String, Function>();
16 Function _notFound; 18 Function _notFound;
17 19
18 DispatchingServer( 20 DispatchingServer(
(...skipping 19 matching lines...) Expand all
38 } 40 }
39 41
40 /// Interface of the HTTP server: 42 /// Interface of the HTTP server:
41 /// 43 ///
42 /// /echo: This will stream the data received in the request stream back 44 /// /echo: This will stream the data received in the request stream back
43 /// to the client. 45 /// to the client.
44 /// /root_dart/X: This will serve the corresponding file from the dart 46 /// /root_dart/X: This will serve the corresponding file from the dart
45 /// directory (i.e. '$DartDirectory/X'). 47 /// directory (i.e. '$DartDirectory/X').
46 /// /root_build/X: This will serve the corresponding file from the build 48 /// /root_build/X: This will serve the corresponding file from the build
47 /// directory (i.e. '$BuildDirectory/X'). 49 /// directory (i.e. '$BuildDirectory/X').
50 /// /FOO/packages/PAZ/BAR: This will serve files from the packages listed in
51 /// the package spec .packages. Supports a package
52 /// root or custom package spec, and uses [dart_dir]/.packages
53 /// as the default. This will serve file lib/BAR from the package PAZ.
48 /// /ws: This will upgrade the connection to a WebSocket connection and echo 54 /// /ws: This will upgrade the connection to a WebSocket connection and echo
49 /// all data back to the client. 55 /// all data back to the client.
50 /// 56 ///
51 /// In case a path does not refer to a file but rather to a directory, a 57 /// In case a path does not refer to a file but rather to a directory, a
52 /// directory listing will be displayed. 58 /// directory listing will be displayed.
53 59
54 const PREFIX_BUILDDIR = 'root_build'; 60 const PREFIX_BUILDDIR = 'root_build';
55 const PREFIX_DARTDIR = 'root_dart'; 61 const PREFIX_DARTDIR = 'root_dart';
56 62
57 void main(List<String> arguments) { 63 void main(List<String> arguments) {
58 // This script is in [dart]/tools/testing/dart. 64 // This script is in [dart]/tools/testing/dart.
59 TestUtils.setDartDirUri(Platform.script.resolve('../../..')); 65 TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
60 /** Convenience method for local testing. */ 66 /** Convenience method for local testing. */
61 var parser = new ArgParser(); 67 var parser = new ArgParser();
62 parser.addOption('port', 68 parser.addOption('port',
63 abbr: 'p', 69 abbr: 'p',
64 help: 'The main server port we wish to respond to requests.', 70 help: 'The main server port we wish to respond to requests.',
65 defaultsTo: '0'); 71 defaultsTo: '0');
66 parser.addOption('crossOriginPort', 72 parser.addOption('crossOriginPort',
67 abbr: 'c', 73 abbr: 'c',
68 help: 'A different port that accepts request from the main server port.', 74 help: 'A different port that accepts request from the main server port.',
69 defaultsTo: '0'); 75 defaultsTo: '0');
70 parser.addFlag('help', 76 parser.addFlag('help',
71 abbr: 'h', negatable: false, help: 'Print this usage information.'); 77 abbr: 'h', negatable: false, help: 'Print this usage information.');
72 parser.addOption('build-directory', help: 'The build directory to use.'); 78 parser.addOption('build-directory', help: 'The build directory to use.');
73 parser.addOption('package-root', help: 'Obsolete unsupported option'); 79 parser.addOption('package-root', help: 'The package root to use.');
74 parser.addOption('packages', help: 'Obsolete unsupported option'); 80 parser.addOption('packages', help: 'The package spec file to use.');
75 parser.addOption('network', 81 parser.addOption('network',
76 help: 'The network interface to use.', defaultsTo: '0.0.0.0'); 82 help: 'The network interface to use.', defaultsTo: '0.0.0.0');
77 parser.addFlag('csp', 83 parser.addFlag('csp',
78 help: 'Use Content Security Policy restrictions.', defaultsTo: false); 84 help: 'Use Content Security Policy restrictions.', defaultsTo: false);
79 parser.addOption('runtime', 85 parser.addOption('runtime',
80 help: 'The runtime we are using (for csp flags).', defaultsTo: 'none'); 86 help: 'The runtime we are using (for csp flags).', defaultsTo: 'none');
81 87
82 var args = parser.parse(arguments); 88 var args = parser.parse(arguments);
83 if (args['help'] as bool) { 89 if (args['help'] as bool) {
84 print(parser.getUsage()); 90 print(parser.getUsage());
85 } else { 91 } else {
86 var servers = new TestingServers(args['build-directory'] as String, 92 var servers = new TestingServers(
87 args['csp'] as bool, Runtime.find(args['runtime'] as String), null); 93 args['build-directory'] as String,
94 args['csp'] as bool,
95 Runtime.find(args['runtime'] as String),
96 null,
97 args['package-root'] as String,
98 args['packages'] as String);
88 var port = int.parse(args['port'] as String); 99 var port = int.parse(args['port'] as String);
89 var crossOriginPort = int.parse(args['crossOriginPort'] as String); 100 var crossOriginPort = int.parse(args['crossOriginPort'] as String);
90 servers 101 servers
91 .startServers(args['network'] as String, 102 .startServers(args['network'] as String,
92 port: port, crossOriginPort: crossOriginPort) 103 port: port, crossOriginPort: crossOriginPort)
93 .then((_) { 104 .then((_) {
94 DebugLogger.info('Server listening on port ${servers.port}'); 105 DebugLogger.info('Server listening on port ${servers.port}');
95 DebugLogger.info('Server listening on port ${servers.crossOriginPort}'); 106 DebugLogger.info('Server listening on port ${servers.crossOriginPort}');
96 }); 107 });
97 } 108 }
98 } 109 }
99 110
100 /** 111 /**
101 * Runs a set of servers that are initialized specifically for the needs of our 112 * Runs a set of servers that are initialized specifically for the needs of our
102 * test framework. 113 * test framework, such as dealing with package-root.
103 */ 114 */
104 class TestingServers { 115 class TestingServers {
105 static final _CACHE_EXPIRATION_IN_SECONDS = 30; 116 static final _CACHE_EXPIRATION_IN_SECONDS = 30;
106 static final _HARMLESS_REQUEST_PATH_ENDINGS = [ 117 static final _HARMLESS_REQUEST_PATH_ENDINGS = [
107 "/apple-touch-icon.png", 118 "/apple-touch-icon.png",
108 "/apple-touch-icon-precomposed.png", 119 "/apple-touch-icon-precomposed.png",
109 "/favicon.ico", 120 "/favicon.ico",
110 "/foo", 121 "/foo",
111 "/bar", 122 "/bar",
112 "/NonExistingFile", 123 "/NonExistingFile",
113 "IntentionallyMissingFile", 124 "IntentionallyMissingFile",
114 ]; 125 ];
115 126
116 final List<HttpServer> _serverList = []; 127 final List<HttpServer> _serverList = [];
117 Uri _buildDirectory; 128 Uri _buildDirectory;
118 Uri _dartDirectory; 129 Uri _dartDirectory;
130 Uri _packageRoot;
131 Uri _packages;
119 final bool useContentSecurityPolicy; 132 final bool useContentSecurityPolicy;
120 final Runtime runtime; 133 final Runtime runtime;
121 DispatchingServer _server; 134 DispatchingServer _server;
135 SyncPackageResolver _resolver;
122 136
123 TestingServers(String buildDirectory, this.useContentSecurityPolicy, 137 TestingServers(String buildDirectory, this.useContentSecurityPolicy,
124 [this.runtime = Runtime.none, String dartDirectory]) { 138 [this.runtime = Runtime.none,
139 String dartDirectory,
140 String packageRoot,
141 String packages]) {
125 _buildDirectory = Uri.base.resolveUri(new Uri.directory(buildDirectory)); 142 _buildDirectory = Uri.base.resolveUri(new Uri.directory(buildDirectory));
126 if (dartDirectory == null) { 143 if (dartDirectory == null) {
127 _dartDirectory = TestUtils.dartDirUri; 144 _dartDirectory = TestUtils.dartDirUri;
128 } else { 145 } else {
129 _dartDirectory = Uri.base.resolveUri(new Uri.directory(dartDirectory)); 146 _dartDirectory = Uri.base.resolveUri(new Uri.directory(dartDirectory));
130 } 147 }
148 if (packageRoot == null) {
149 if (packages == null) {
150 _packages = _dartDirectory.resolve('.packages');
151 } else {
152 _packages = new Uri.file(packages);
153 }
154 } else {
155 _packageRoot = new Uri.directory(packageRoot);
156 }
131 } 157 }
132 158
133 int get port => _serverList[0].port; 159 int get port => _serverList[0].port;
134 int get crossOriginPort => _serverList[1].port; 160 int get crossOriginPort => _serverList[1].port;
135 DispatchingServer get server => _server; 161 DispatchingServer get server => _server;
136 162
137 /** 163 /**
138 * [startServers] will start two Http servers. 164 * [startServers] will start two Http servers.
139 * The first server listens on [port] and sets 165 * The first server listens on [port] and sets
140 * "Access-Control-Allow-Origin: *" 166 * "Access-Control-Allow-Origin: *"
141 * The second server listens on [crossOriginPort] and sets 167 * The second server listens on [crossOriginPort] and sets
142 * "Access-Control-Allow-Origin: client:port1 168 * "Access-Control-Allow-Origin: client:port1
143 * "Access-Control-Allow-Credentials: true" 169 * "Access-Control-Allow-Credentials: true"
144 */ 170 */
145 Future startServers(String host, 171 Future startServers(String host,
146 {int port: 0, int crossOriginPort: 0}) async { 172 {int port: 0, int crossOriginPort: 0}) async {
173 if (_packages != null) {
174 _resolver = await SyncPackageResolver.loadConfig(_packages);
175 } else {
176 _resolver = new SyncPackageResolver.root(_packageRoot);
177 }
147 _server = await _startHttpServer(host, port: port); 178 _server = await _startHttpServer(host, port: port);
148 await _startHttpServer(host, 179 await _startHttpServer(host,
149 port: crossOriginPort, allowedPort: _serverList[0].port); 180 port: crossOriginPort, allowedPort: _serverList[0].port);
150 } 181 }
151 182
152 String httpServerCommandLine() { 183 String httpServerCommandLine() {
153 var dart = Platform.resolvedExecutable; 184 var dart = Platform.resolvedExecutable;
154 var script = _dartDirectory.resolve('tools/testing/dart/http_server.dart'); 185 var script = _dartDirectory.resolve('tools/testing/dart/http_server.dart');
155 var buildDirectory = _buildDirectory.toFilePath(); 186 var buildDirectory = _buildDirectory.toFilePath();
156 var command = [ 187 var command = [
157 dart, 188 dart,
158 script.toFilePath(), 189 script.toFilePath(),
159 '-p', 190 '-p',
160 port, 191 port,
161 '-c', 192 '-c',
162 crossOriginPort, 193 crossOriginPort,
163 '--build-directory=$buildDirectory', 194 '--build-directory=$buildDirectory',
164 '--runtime=${runtime.name}' 195 '--runtime=${runtime.name}'
165 ]; 196 ];
166 if (useContentSecurityPolicy) { 197 if (useContentSecurityPolicy) {
167 command.add('--csp'); 198 command.add('--csp');
168 } 199 }
200 if (_packages != null) {
201 command.add('--packages=${_packages.toFilePath()}');
202 } else if (_packageRoot != null) {
203 command.add('--package-root=${_packageRoot.toFilePath()}');
204 }
169 return command.join(' '); 205 return command.join(' ');
170 } 206 }
171 207
172 void stopServers() { 208 void stopServers() {
173 for (var server in _serverList) { 209 for (var server in _serverList) {
174 server.close(); 210 server.close();
175 } 211 }
176 } 212 }
177 213
178 void _onError(e) { 214 void _onError(e) {
179 DebugLogger.error('HttpServer: an error occured', e); 215 DebugLogger.error('HttpServer: an error occured', e);
180 } 216 }
181 217
182 Future<DispatchingServer> _startHttpServer(String host, 218 Future<DispatchingServer> _startHttpServer(String host,
183 {int port: 0, int allowedPort: -1}) { 219 {int port: 0, int allowedPort: -1}) {
184 return HttpServer.bind(host, port).then((HttpServer httpServer) { 220 return HttpServer.bind(host, port).then((HttpServer httpServer) {
185 var server = new DispatchingServer(httpServer, _onError, _sendNotFound); 221 var server = new DispatchingServer(httpServer, _onError, _sendNotFound);
186 server.addHandler('/echo', _handleEchoRequest); 222 server.addHandler('/echo', _handleEchoRequest);
187 server.addHandler('/ws', _handleWebSocketRequest); 223 server.addHandler('/ws', _handleWebSocketRequest);
188 fileHandler(HttpRequest request) { 224 fileHandler(HttpRequest request) {
189 _handleFileOrDirectoryRequest(request, allowedPort); 225 _handleFileOrDirectoryRequest(request, allowedPort);
190 } 226 }
191 227
192 server.addHandler('/$PREFIX_BUILDDIR', fileHandler); 228 server.addHandler('/$PREFIX_BUILDDIR', fileHandler);
193 server.addHandler('/$PREFIX_DARTDIR', fileHandler); 229 server.addHandler('/$PREFIX_DARTDIR', fileHandler);
230 server.addHandler('/packages', fileHandler);
194 _serverList.add(httpServer); 231 _serverList.add(httpServer);
195 return server; 232 return server;
196 }); 233 });
197 } 234 }
198 235
199 Future _handleFileOrDirectoryRequest( 236 Future _handleFileOrDirectoryRequest(
200 HttpRequest request, int allowedPort) async { 237 HttpRequest request, int allowedPort) async {
201 // Enable browsers to cache file/directory responses. 238 // Enable browsers to cache file/directory responses.
202 var response = request.response; 239 var response = request.response;
203 response.headers 240 response.headers
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 }).catchError((e) { 293 }).catchError((e) {
257 DebugLogger.warning( 294 DebugLogger.warning(
258 'HttpServer: error while transforming to WebSocket', e); 295 'HttpServer: error while transforming to WebSocket', e);
259 }); 296 });
260 } 297 }
261 298
262 Uri _getFileUriFromRequestUri(Uri request) { 299 Uri _getFileUriFromRequestUri(Uri request) {
263 // Go to the top of the file to see an explanation of the URL path scheme. 300 // Go to the top of the file to see an explanation of the URL path scheme.
264 List<String> pathSegments = request.normalizePath().pathSegments; 301 List<String> pathSegments = request.normalizePath().pathSegments;
265 if (pathSegments.length == 0) return null; 302 if (pathSegments.length == 0) return null;
303 int packagesIndex = pathSegments.indexOf('packages');
304 if (packagesIndex != -1) {
305 var packageUri = new Uri(
306 scheme: 'package',
307 pathSegments: pathSegments.skip(packagesIndex + 1));
308 return _resolver.resolveUri(packageUri);
309 }
266 if (pathSegments[0] == PREFIX_BUILDDIR) { 310 if (pathSegments[0] == PREFIX_BUILDDIR) {
267 return _buildDirectory.resolve(pathSegments.skip(1).join('/')); 311 return _buildDirectory.resolve(pathSegments.skip(1).join('/'));
268 } 312 }
269 if (pathSegments[0] == PREFIX_DARTDIR) { 313 if (pathSegments[0] == PREFIX_DARTDIR) {
270 return _dartDirectory.resolve(pathSegments.skip(1).join('/')); 314 return _dartDirectory.resolve(pathSegments.skip(1).join('/'));
271 } 315 }
272 return null; 316 return null;
273 } 317 }
274 318
275 Future<List<_Entry>> _listDirectory(Directory directory) { 319 Future<List<_Entry>> _listDirectory(Directory directory) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 class _Entry implements Comparable<_Entry> { 468 class _Entry implements Comparable<_Entry> {
425 final String name; 469 final String name;
426 final String displayName; 470 final String displayName;
427 471
428 _Entry(this.name, this.displayName); 472 _Entry(this.name, this.displayName);
429 473
430 int compareTo(_Entry other) { 474 int compareTo(_Entry other) {
431 return name.compareTo(other.name); 475 return name.compareTo(other.name);
432 } 476 }
433 } 477 }
OLDNEW
« no previous file with comments | « tools/testing/dart/configuration.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698