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

Unified Diff: tools/testing/dart/http_server.dart

Issue 841193003: cleanup to tools/testing/dart (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: one last bit Created 5 years, 11 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 | « tools/testing/dart/html_test.dart ('k') | tools/testing/dart/launch_browser.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/testing/dart/http_server.dart
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
deleted file mode 100644
index 7f5fae75bc4dee64baf58831ba2bf50a50a5af10..0000000000000000000000000000000000000000
--- a/tools/testing/dart/http_server.dart
+++ /dev/null
@@ -1,465 +0,0 @@
-// 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.
-
-library http_server;
-
-import 'dart:async';
-import 'dart:io';
-
-import 'dart:convert' show
- HtmlEscape;
-
-import 'path.dart';
-import 'test_suite.dart'; // For TestUtils.
-// TODO(efortuna): Rewrite to not use the args library and simply take an
-// expected number of arguments, so test.dart doesn't rely on the args library?
-// See discussion on https://codereview.chromium.org/11931025/.
-import 'vendored_pkg/args/args.dart';
-import 'utils.dart';
-
-class DispatchingServer {
- HttpServer server;
- Map<String, Function> _handlers = new Map<String, Function>();
- Function _notFound;
-
- DispatchingServer(this.server,
- void onError(e),
- void this._notFound(HttpRequest request)) {
- server.listen(_dispatchRequest, onError: onError);
- }
-
- void addHandler(String prefix, void handler(HttpRequest request)) {
- _handlers[prefix] = handler;
- }
-
- void _dispatchRequest(HttpRequest request) {
- // If the request path matches a prefix in _handlers, send it to that
- // handler. Otherwise, run the notFound handler.
- for (String prefix in _handlers.keys) {
- if (request.uri.path.startsWith(prefix)) {
- _handlers[prefix](request);
- return;
- }
- }
- _notFound(request);
- }
-}
-
-
-
-/// Interface of the HTTP server:
-///
-/// /echo: This will stream the data received in the request stream back
-/// to the client.
-/// /root_dart/X: This will serve the corresponding file from the dart
-/// directory (i.e. '$DartDirectory/X').
-/// /root_build/X: This will serve the corresponding file from the build
-/// directory (i.e. '$BuildDirectory/X').
-/// /FOO/packages/BAR: This will serve the corresponding file from the packages
-/// directory (i.e. '$BuildDirectory/packages/BAR') or the
-/// passed-in package root
-/// /ws: This will upgrade the connection to a WebSocket connection and echo
-/// all data back to the client.
-///
-/// In case a path does not refer to a file but rather to a directory, a
-/// directory listing will be displayed.
-
-const PREFIX_BUILDDIR = 'root_build';
-const PREFIX_DARTDIR = 'root_dart';
-
-// TODO(kustermann,ricow): We could change this to the following scheme:
-// http://host:port/root_packages/X -> $BuildDir/packages/X
-// Issue: 8368
-
-main(List<String> arguments) {
- // This script is in [dart]/tools/testing/dart.
- TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
- /** Convenience method for local testing. */
- var parser = new ArgParser();
- parser.addOption('port', abbr: 'p',
- help: 'The main server port we wish to respond to requests.',
- defaultsTo: '0');
- parser.addOption('crossOriginPort', abbr: 'c',
- help: 'A different port that accepts request from the main server port.',
- defaultsTo: '0');
- parser.addFlag('help', abbr: 'h', negatable: false,
- help: 'Print this usage information.');
- parser.addOption('build-directory', help: 'The build directory to use.');
- parser.addOption('package-root', help: 'The package root to use.');
- parser.addOption('network', help: 'The network interface to use.',
- defaultsTo: '0.0.0.0');
- parser.addFlag('csp', help: 'Use Content Security Policy restrictions.',
- defaultsTo: false);
- parser.addOption('runtime', help: 'The runtime we are using (for csp flags).',
- defaultsTo: 'none');
-
- var args = parser.parse(arguments);
- if (args['help']) {
- print(parser.getUsage());
- } else {
- var servers = new TestingServers(new Path(args['build-directory']),
- args['csp'],
- args['runtime'],
- null,
- args['package-root']);
- var port = int.parse(args['port']);
- var crossOriginPort = int.parse(args['crossOriginPort']);
- servers.startServers(args['network'],
- port: port,
- crossOriginPort: crossOriginPort).then((_) {
- DebugLogger.info('Server listening on port ${servers.port}');
- DebugLogger.info('Server listening on port ${servers.crossOriginPort}');
- });
- }
-}
-
-/**
- * Runs a set of servers that are initialized specifically for the needs of our
- * test framework, such as dealing with package-root.
- */
-class TestingServers {
- static final _CACHE_EXPIRATION_IN_SECONDS = 30;
- static final _HARMLESS_REQUEST_PATH_ENDINGS = [
- "/apple-touch-icon.png",
- "/apple-touch-icon-precomposed.png",
- "/favicon.ico",
- "/foo",
- "/bar",
- "/NonExistingFile",
- "IntentionallyMissingFile",
- ];
-
- List _serverList = [];
- Path _buildDirectory = null;
- Path _dartDirectory = null;
- Path _packageRoot;
- final bool useContentSecurityPolicy;
- final String runtime;
- DispatchingServer _server;
-
- TestingServers(Path buildDirectory,
- this.useContentSecurityPolicy,
- [String this.runtime = 'none', String dartDirectory,
- String packageRoot]) {
- _buildDirectory = TestUtils.absolutePath(buildDirectory);
- _dartDirectory = dartDirectory == null ? TestUtils.dartDir
- : new Path(dartDirectory);
- _packageRoot = packageRoot == null ?
- _buildDirectory.append('packages') :
- new Path(packageRoot);
- }
-
- int get port => _serverList[0].port;
- int get crossOriginPort => _serverList[1].port;
- DispatchingServer get server => _server;
-
- /**
- * [startServers] will start two Http servers.
- * The first server listens on [port] and sets
- * "Access-Control-Allow-Origin: *"
- * The second server listens on [crossOriginPort] and sets
- * "Access-Control-Allow-Origin: client:port1
- * "Access-Control-Allow-Credentials: true"
- */
- Future startServers(String host, {int port: 0, int crossOriginPort: 0}) {
- return _startHttpServer(host, port: port).then((server) {
- _server = server;
- return _startHttpServer(host,
- port: crossOriginPort,
- allowedPort:_serverList[0].port);
- });
- }
-
- String httpServerCommandline() {
- var dart = TestUtils.dartTestExecutable.toNativePath();
- var dartDir = TestUtils.dartDir;
- var script = dartDir.join(new Path("tools/testing/dart/http_server.dart"));
- var buildDirectory = _buildDirectory.toNativePath();
- var csp = useContentSecurityPolicy ? '--csp ' : '';
- return '$dart $script -p $port -c $crossOriginPort $csp'
- '--build-directory=$buildDirectory --runtime=$runtime '
- '--package-root=$_packageRoot';
- }
-
- void stopServers() {
- for (var server in _serverList) {
- server.close();
- }
- }
-
- void _onError(e) {
- DebugLogger.error('HttpServer: an error occured', e);
- }
-
- Future _startHttpServer(String host, {int port: 0, int allowedPort: -1}) {
- return HttpServer.bind(host, port).then((HttpServer httpServer) {
- var server = new DispatchingServer(httpServer, _onError, _sendNotFound);
- server.addHandler('/echo', _handleEchoRequest);
- server.addHandler('/ws', _handleWebSocketRequest);
- fileHandler(request) {
- _handleFileOrDirectoryRequest(request, allowedPort);
- }
- server.addHandler('/$PREFIX_BUILDDIR', fileHandler);
- server.addHandler('/$PREFIX_DARTDIR', fileHandler);
- server.addHandler('/packages', fileHandler);
- _serverList.add(httpServer);
- return server;
- });
- }
-
- void _handleFileOrDirectoryRequest(HttpRequest request,
- int allowedPort) {
- // Enable browsers to cache file/directory responses.
- var response = request.response;
- response.headers.set("Cache-Control",
- "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
- var path = _getFilePathFromRequestPath(request.uri.path);
- if (path != null) {
- var file = new File(path.toNativePath());
- file.exists().then((exists) {
- if (exists) {
- _sendFileContent(request, response, allowedPort, path, file);
- } else {
- var directory = new Directory(path.toNativePath());
- directory.exists().then((exists) {
- if (exists) {
- _listDirectory(directory).then((entries) {
- _sendDirectoryListing(entries, request, response);
- });
- } else {
- _sendNotFound(request);
- }
- });
- }
- });
- } else {
- if (request.uri.path == '/') {
- var entries = [new _Entry('root_dart', 'root_dart/'),
- new _Entry('root_build', 'root_build/'),
- new _Entry('echo', 'echo')];
- _sendDirectoryListing(entries, request, response);
- } else {
- _sendNotFound(request);
- }
- }
- }
-
- void _handleEchoRequest(HttpRequest request) {
- request.response.headers.set("Access-Control-Allow-Origin", "*");
- request.pipe(request.response).catchError((e) {
- DebugLogger.warning(
- 'HttpServer: error while closing the response stream', e);
- });
- }
-
- void _handleWebSocketRequest(HttpRequest request) {
- WebSocketTransformer.upgrade(request).then((websocket) {
- // We ignore failures to write to the socket, this happens if the browser
- // closes the connection.
- websocket.done.catchError((_) {});
- websocket.listen((data) {
- websocket.add(data);
- websocket.close();
- }, onError: (e) {
- DebugLogger.warning('HttpServer: error while echoing to WebSocket', e);
- });
- }).catchError((e) {
- DebugLogger.warning(
- 'HttpServer: error while transforming to WebSocket', e);
- });
- }
-
- Path _getFilePathFromRequestPath(String urlRequestPath) {
- // Go to the top of the file to see an explanation of the URL path scheme.
- var requestPath = new Path(urlRequestPath.substring(1)).canonicalize();
- var pathSegments = requestPath.segments();
- if (pathSegments.length > 0) {
- var basePath;
- var relativePath;
- if (pathSegments[0] == PREFIX_BUILDDIR) {
- basePath = _buildDirectory;
- relativePath = new Path(
- pathSegments.skip(1).join('/'));
- } else if (pathSegments[0] == PREFIX_DARTDIR) {
- basePath = _dartDirectory;
- relativePath = new Path(
- pathSegments.skip(1).join('/'));
- }
- var packagesIndex = pathSegments.indexOf('packages');
- if (packagesIndex != -1) {
- var start = packagesIndex + 1;
- basePath = _packageRoot;
- relativePath = new Path(pathSegments.skip(start).join('/'));
- }
- if (basePath != null && relativePath != null) {
- return basePath.join(relativePath);
- }
- }
- return null;
- }
-
- Future<List<_Entry>> _listDirectory(Directory directory) {
- var completer = new Completer();
- var entries = [];
-
- directory.list().listen(
- (FileSystemEntity fse) {
- var filename = new Path(fse.path).filename;
- if (fse is File) {
- entries.add(new _Entry(filename, filename));
- } else if (fse is Directory) {
- entries.add(new _Entry(filename, '$filename/'));
- }
- },
- onDone: () {
- completer.complete(entries);
- });
- return completer.future;
- }
-
- void _sendDirectoryListing(List<_Entry> entries,
- HttpRequest request,
- HttpResponse response) {
- response.headers.set('Content-Type', 'text/html');
- var header = '''<!DOCTYPE html>
- <html>
- <head>
- <title>${request.uri.path}</title>
- </head>
- <body>
- <code>
- <div>${request.uri.path}</div>
- <hr/>
- <ul>''';
- var footer = '''
- </ul>
- </code>
- </body>
- </html>''';
-
-
- entries.sort();
- response.write(header);
- for (var entry in entries) {
- response.write(
- '<li><a href="${new Path(request.uri.path).append(entry.name)}">'
- '${entry.displayName}</a></li>');
- }
- response.write(footer);
- response.close();
- response.done.catchError((e) {
- DebugLogger.warning(
- 'HttpServer: error while closing the response stream', e);
- });
- }
-
- void _sendFileContent(HttpRequest request,
- HttpResponse response,
- int allowedPort,
- Path path,
- File file) {
- if (allowedPort != -1) {
- var headerOrigin = request.headers.value('Origin');
- var allowedOrigin;
- if (headerOrigin != null) {
- var origin = Uri.parse(headerOrigin);
- // Allow loading from http://*:$allowedPort in browsers.
- allowedOrigin =
- '${origin.scheme}://${origin.host}:${allowedPort}';
- } else {
- // IE10 appears to be bugged and is not sending the Origin header
- // when making CORS requests to the same domain but different port.
- allowedOrigin = '*';
- }
-
-
- response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
- response.headers.set('Access-Control-Allow-Credentials', 'true');
- } else {
- // No allowedPort specified. Allow from anywhere (but cross-origin
- // requests *with credentials* will fail because you can't use "*").
- response.headers.set("Access-Control-Allow-Origin", "*");
- }
- if (useContentSecurityPolicy) {
- // Chrome respects the standardized Content-Security-Policy header,
- // whereas Firefox and IE10 use X-Content-Security-Policy. Safari
- // still uses the WebKit- prefixed version.
- var content_header_value = "script-src 'self'; object-src 'self'";
- for (var header in ["Content-Security-Policy",
- "X-Content-Security-Policy"]) {
- response.headers.set(header, content_header_value);
- }
- if (const ["safari"].contains(runtime)) {
- response.headers.set("X-WebKit-CSP", content_header_value);
- }
- }
- if (path.filename.endsWith('.html')) {
- response.headers.set('Content-Type', 'text/html');
- } else if (path.filename.endsWith('.js')) {
- response.headers.set('Content-Type', 'application/javascript');
- } else if (path.filename.endsWith('.dart')) {
- response.headers.set('Content-Type', 'application/dart');
- } else if (path.filename.endsWith('.css')) {
- response.headers.set('Content-Type', 'text/css');
- } else if (path.filename.endsWith('.xml')) {
- response.headers.set('Content-Type', 'text/xml');
- }
- response.headers.removeAll("X-Frame-Options");
- file.openRead().pipe(response).catchError((e) {
- DebugLogger.warning(
- 'HttpServer: error while closing the response stream', e);
- });
- }
-
- void _sendNotFound(HttpRequest request) {
- bool isHarmlessPath(String path) {
- return _HARMLESS_REQUEST_PATH_ENDINGS.any((pattern) {
- return path.contains(pattern);
- });
- }
- if (!isHarmlessPath(request.uri.path)) {
- DebugLogger.warning('HttpServer: could not find file for request path: '
- '"${request.uri.path}"');
- }
- var response = request.response;
- response.statusCode = HttpStatus.NOT_FOUND;
-
- // Send a nice HTML page detailing the error message. Most browsers expect
- // this, for example, Chrome will simply display a blank page if you don't
- // provide any information. A nice side effect of this is to work around
- // Firefox bug 1016313
- // (https://bugzilla.mozilla.org/show_bug.cgi?id=1016313).
- response.headers.set(HttpHeaders.CONTENT_TYPE, 'text/html');
- String escapedPath = const HtmlEscape().convert(request.uri.path);
- response.write("""
-<!DOCTYPE html>
-<html lang='en'>
-<head>
-<title>Not Found</title>
-</head>
-<body>
-<h1>Not Found</h1>
-<p style='white-space:pre'>The file '$escapedPath\' could not be found.</p>
-</body>
-</html>
-""");
- response.close();
- response.done.catchError((e) {
- DebugLogger.warning(
- 'HttpServer: error while closing the response stream', e);
- });
- }
-}
-
-// Helper class for displaying directory listings.
-class _Entry implements Comparable {
- final String name;
- final String displayName;
-
- _Entry(this.name, this.displayName);
-
- int compareTo(_Entry other) {
- return name.compareTo(other.name);
- }
-}
« no previous file with comments | « tools/testing/dart/html_test.dart ('k') | tools/testing/dart/launch_browser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698