Index: tools/testing/dart/http_server.dart |
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart |
index 84a5b771913bb4f090f67243b8ed16cb8aca00e3..06b87da3960551c77cfe4386dad504c64c41d7e0 100644 |
--- a/tools/testing/dart/http_server.dart |
+++ b/tools/testing/dart/http_server.dart |
@@ -6,6 +6,7 @@ library http_server; |
import 'dart:io'; |
import 'dart:isolate'; |
+import 'dart:uri'; |
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? |
@@ -28,6 +29,8 @@ main() { |
parser.addFlag('help', abbr: 'h', negatable: false, |
help: 'Print this usage information.'); |
parser.addOption('package-root', help: 'The package root to use.'); |
+ parser.addOption('network', help: 'The network interface to use.', |
+ defaultsTo: '127.0.0.1'); |
var args = parser.parse(new Options().arguments); |
if (args['help']) { |
print(parser.getUsage()); |
@@ -41,11 +44,12 @@ main() { |
.canonicalize() |
.toNativePath(); |
TestingServerRunner._packageRootDir = new Path(args['package-root']); |
- TestingServerRunner.startHttpServer('127.0.0.1', |
+ var network = args['network']; |
+ TestingServerRunner.startHttpServer(network, |
port: int.parse(args['port'])); |
print('Server listening on port ' |
'${TestingServerRunner.serverList[0].port}.'); |
- TestingServerRunner.startHttpServer('127.0.0.1', |
+ TestingServerRunner.startHttpServer(network, |
allowedPort: TestingServerRunner.serverList[0].port, port: |
int.parse(args['crossOriginPort'])); |
print( |
@@ -93,10 +97,14 @@ class TestingServerRunner { |
file.exists().then((exists) { |
if (exists) { |
if (allowedPort != -1) { |
- // Allow loading from localhost:$allowedPort in browsers. |
- resp.headers.set("Access-Control-Allow-Origin", |
- "http://127.0.0.1:$allowedPort"); |
- resp.headers.set('Access-Control-Allow-Credentials', 'true'); |
+ if (request.headers.value('Origin') != null) { |
+ var origin = new Uri(request.headers.value('Origin')); |
+ // Allow loading from http://*:$allowedPort in browsers. |
+ var allowedOrigin = |
+ '${origin.scheme}://${origin.domain}:${allowedPort}'; |
+ resp.headers.set("Access-Control-Allow-Origin", allowedOrigin); |
+ resp.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 "*"). |
@@ -111,16 +119,14 @@ class TestingServerRunner { |
} |
file.openInputStream().pipe(resp.outputStream); |
} else { |
- resp.statusCode = HttpStatus.NOT_FOUND; |
- try { |
- resp.outputStream.close(); |
- } catch (e) { |
- if (e is StreamException) { |
- print('Test http_server error closing the response stream: $e'); |
+ var directory = new Directory.fromPath(path); |
+ directory.exists().then((exists) { |
+ if (!exists) { |
+ sendNotFound(resp); |
} else { |
- throw e; |
+ sendDirectoryListing(directory, request, resp); |
} |
- } |
+ }); |
} |
}); |
}; |
@@ -136,7 +142,84 @@ class TestingServerRunner { |
serverList.add(httpServer); |
} |
+ static void sendNotFound(HttpResponse response) { |
+ response.statusCode = HttpStatus.NOT_FOUND; |
+ try { |
+ response.outputStream.close(); |
+ } catch (e) { |
+ if (e is StreamException) { |
+ print('Test http_server error closing the response stream: $e'); |
+ } else { |
+ throw e; |
+ } |
+ } |
+ } |
+ |
+ /** |
+ * Sends a simple listing of all the files and sub-directories within |
+ * directory. |
+ * |
+ * This is intended to make it easier to browse tests when manually running |
+ * tests against this test server. |
+ */ |
+ static void sendDirectoryListing(Directory directory, HttpRequest request, |
+ HttpResponse response) { |
+ response.headers.set('Content-Type', 'text/html'); |
+ var header = '''<!DOCTYPE html> |
+ <html> |
+ <head> |
+ <title>${request.path}</title> |
+ </head> |
+ <body> |
+ <code> |
+ <div>${request.path}</div> |
+ <hr/> |
+ <ul>'''; |
+ var footer = ''' |
+ </ul> |
+ </code> |
+ </body> |
+ </html>'''; |
+ |
+ var entries = []; |
+ |
+ directory.list() |
+ ..onFile = (filepath) { |
+ var filename = new Path(filepath).filename; |
+ entries.add(new _Entry(filename, filename)); |
+ } |
+ ..onDir = (dirpath) { |
+ var filename = new Path(dirpath).filename; |
+ entries.add(new _Entry(filename, '$filename/')); |
+ } |
+ ..onDone = (_) { |
+ var requestPath = new Path.raw(request.path); |
+ entries.sort(); |
+ |
+ response.outputStream.writeString(header); |
+ for (var entry in entries) { |
+ response.outputStream.writeString( |
+ '<li><a href="${requestPath.append(entry.name)}">' |
+ '${entry.displayName}</a></li>'); |
+ } |
+ response.outputStream.writeString(footer); |
+ response.outputStream.close(); |
+ }; |
+ } |
+ |
static terminateHttpServers() { |
for (var server in serverList) server.close(); |
} |
} |
+ |
+// Helper class for displaying directory listings. |
+class _Entry { |
+ final String name; |
+ final String displayName; |
+ |
+ _Entry(this.name, this.displayName); |
+ |
+ int compareTo(_Entry other) { |
+ return name.compareTo(other.name); |
+ } |
+} |