mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 15:17:07 +00:00
Add support for package spec to testing HttpServer.
BUG=https://github.com/dart-lang/sdk/issues/27065 R=terry@google.com Review URL: https://codereview.chromium.org/2347423003 .
This commit is contained in:
parent
57f1193c01
commit
88a64b77bf
3 changed files with 95 additions and 102 deletions
|
@ -1,9 +0,0 @@
|
||||||
# The test runner logic depends on `package:yaml`, because it is not structured
|
|
||||||
# as a pub package, we generated this file manually to contain all of yaml's
|
|
||||||
# transitive dependencies.
|
|
||||||
charcode:../third_party/pkg/charcode/lib/
|
|
||||||
collection:../third_party/pkg/collection/lib/
|
|
||||||
path:../third_party/pkg/path/lib/
|
|
||||||
source_span:../third_party/pkg/source_span/lib/
|
|
||||||
string_scanner:../third_party/pkg/string_scanner/lib/
|
|
||||||
yaml:../third_party/pkg/yaml/lib/
|
|
|
@ -9,13 +9,10 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'dart:convert' show HtmlEscape;
|
import 'dart:convert' show HtmlEscape;
|
||||||
|
|
||||||
import 'path.dart';
|
|
||||||
import 'test_suite.dart'; // For TestUtils.
|
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 'vendored_pkg/args/args.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
import 'package:package_resolver/package_resolver.dart';
|
||||||
|
|
||||||
class DispatchingServer {
|
class DispatchingServer {
|
||||||
HttpServer server;
|
HttpServer server;
|
||||||
|
@ -52,9 +49,10 @@ class DispatchingServer {
|
||||||
/// directory (i.e. '$DartDirectory/X').
|
/// directory (i.e. '$DartDirectory/X').
|
||||||
/// /root_build/X: This will serve the corresponding file from the build
|
/// /root_build/X: This will serve the corresponding file from the build
|
||||||
/// directory (i.e. '$BuildDirectory/X').
|
/// directory (i.e. '$BuildDirectory/X').
|
||||||
/// /FOO/packages/BAR: This will serve the corresponding file from the packages
|
/// /FOO/packages/PAZ/BAR: This will serve files from the packages listed in
|
||||||
/// directory (i.e. '$BuildDirectory/packages/BAR') or the
|
/// the package spec .packages. Supports a package
|
||||||
/// passed-in package root
|
/// root or custom package spec, and uses [dart_dir]/.packages
|
||||||
|
/// as the default. This will serve file lib/BAR from the package PAZ.
|
||||||
/// /ws: This will upgrade the connection to a WebSocket connection and echo
|
/// /ws: This will upgrade the connection to a WebSocket connection and echo
|
||||||
/// all data back to the client.
|
/// all data back to the client.
|
||||||
///
|
///
|
||||||
|
@ -64,10 +62,6 @@ class DispatchingServer {
|
||||||
const PREFIX_BUILDDIR = 'root_build';
|
const PREFIX_BUILDDIR = 'root_build';
|
||||||
const PREFIX_DARTDIR = 'root_dart';
|
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) {
|
main(List<String> arguments) {
|
||||||
// This script is in [dart]/tools/testing/dart.
|
// This script is in [dart]/tools/testing/dart.
|
||||||
TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
|
TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
|
||||||
|
@ -97,7 +91,7 @@ main(List<String> arguments) {
|
||||||
if (args['help']) {
|
if (args['help']) {
|
||||||
print(parser.getUsage());
|
print(parser.getUsage());
|
||||||
} else {
|
} else {
|
||||||
var servers = new TestingServers(new Path(args['build-directory']),
|
var servers = new TestingServers(args['build-directory'],
|
||||||
args['csp'], args['runtime'], null, args['package-root'],
|
args['csp'], args['runtime'], null, args['package-root'],
|
||||||
args['packages']);
|
args['packages']);
|
||||||
var port = int.parse(args['port']);
|
var port = int.parse(args['port']);
|
||||||
|
@ -129,26 +123,35 @@ class TestingServers {
|
||||||
];
|
];
|
||||||
|
|
||||||
List _serverList = [];
|
List _serverList = [];
|
||||||
Path _buildDirectory = null;
|
Uri _buildDirectory = null;
|
||||||
Path _dartDirectory = null;
|
Uri _dartDirectory = null;
|
||||||
Path _packageRoot;
|
Uri _packageRoot;
|
||||||
Path _packages;
|
Uri _packages;
|
||||||
final bool useContentSecurityPolicy;
|
final bool useContentSecurityPolicy;
|
||||||
final String runtime;
|
final String runtime;
|
||||||
DispatchingServer _server;
|
DispatchingServer _server;
|
||||||
|
SyncPackageResolver _resolver;
|
||||||
|
|
||||||
TestingServers(Path buildDirectory, this.useContentSecurityPolicy,
|
TestingServers(String buildDirectory, this.useContentSecurityPolicy,
|
||||||
[String this.runtime = 'none',
|
[String this.runtime = 'none',
|
||||||
String dartDirectory,
|
String dartDirectory,
|
||||||
String packageRoot,
|
String packageRoot,
|
||||||
String packages]) {
|
String packages]) {
|
||||||
_buildDirectory = TestUtils.absolutePath(buildDirectory);
|
_buildDirectory = Uri.base.resolveUri(new Uri.directory(buildDirectory));
|
||||||
_dartDirectory =
|
if (dartDirectory == null) {
|
||||||
dartDirectory == null ? TestUtils.dartDir : new Path(dartDirectory);
|
_dartDirectory = TestUtils.dartDirUri;
|
||||||
_packageRoot = packageRoot == null
|
} else {
|
||||||
? (packages == null ? _buildDirectory.append('packages') : null)
|
_dartDirectory = Uri.base.resolveUri(new Uri.directory(dartDirectory));
|
||||||
: new Path(packageRoot);
|
}
|
||||||
_packages = packages == null ? null : new Path(packages);
|
if (packageRoot == null ) {
|
||||||
|
if (packages == null ) {
|
||||||
|
_packages = _dartDirectory.resolve('.packages');
|
||||||
|
} else {
|
||||||
|
_packages = new Uri.file(packages);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_packageRoot = new Uri.directory(packageRoot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int get port => _serverList[0].port;
|
int get port => _serverList[0].port;
|
||||||
|
@ -163,23 +166,37 @@ class TestingServers {
|
||||||
* "Access-Control-Allow-Origin: client:port1
|
* "Access-Control-Allow-Origin: client:port1
|
||||||
* "Access-Control-Allow-Credentials: true"
|
* "Access-Control-Allow-Credentials: true"
|
||||||
*/
|
*/
|
||||||
Future startServers(String host, {int port: 0, int crossOriginPort: 0}) {
|
Future startServers(String host,
|
||||||
return _startHttpServer(host, port: port).then((server) {
|
{int port: 0,
|
||||||
_server = server;
|
int crossOriginPort: 0}) async {
|
||||||
return _startHttpServer(host,
|
if (_packages != null) {
|
||||||
port: crossOriginPort, allowedPort: _serverList[0].port);
|
_resolver = await SyncPackageResolver.loadConfig(_packages);
|
||||||
});
|
} else {
|
||||||
|
_resolver = new SyncPackageResolver.root(_packageRoot);
|
||||||
|
}
|
||||||
|
_server = await _startHttpServer(host, port: port);
|
||||||
|
await _startHttpServer(host, port: crossOriginPort,
|
||||||
|
allowedPort: _serverList[0].port);
|
||||||
}
|
}
|
||||||
|
|
||||||
String httpServerCommandline() {
|
String httpServerCommandline() {
|
||||||
var dart = Platform.resolvedExecutable;
|
var dart = Platform.resolvedExecutable;
|
||||||
var dartDir = TestUtils.dartDir;
|
var script = _dartDirectory.resolve('tools/testing/dart/http_server.dart');
|
||||||
var script = dartDir.join(new Path("tools/testing/dart/http_server.dart"));
|
var buildDirectory = _buildDirectory.toFilePath();
|
||||||
var buildDirectory = _buildDirectory.toNativePath();
|
var command = [dart, script.toFilePath(),
|
||||||
var csp = useContentSecurityPolicy ? '--csp ' : '';
|
'-p', port,
|
||||||
return '$dart $script -p $port -c $crossOriginPort $csp'
|
'-c', crossOriginPort,
|
||||||
'--build-directory=$buildDirectory --runtime=$runtime '
|
'--build-directory=$buildDirectory',
|
||||||
'--package-root=$_packageRoot';
|
'--runtime=$runtime'];
|
||||||
|
if (useContentSecurityPolicy) {
|
||||||
|
command.add('--csp');
|
||||||
|
}
|
||||||
|
if (_packages != null) {
|
||||||
|
command.add('--packages=${_packages.toFilePath()}');
|
||||||
|
} else if (_packageRoot != null) {
|
||||||
|
command.add('--package-root=${_packageRoot.toFilePath()}');
|
||||||
|
}
|
||||||
|
return command.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopServers() {
|
void stopServers() {
|
||||||
|
@ -208,30 +225,24 @@ class TestingServers {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleFileOrDirectoryRequest(HttpRequest request, int allowedPort) {
|
_handleFileOrDirectoryRequest(HttpRequest request,
|
||||||
|
int allowedPort) async {
|
||||||
// Enable browsers to cache file/directory responses.
|
// Enable browsers to cache file/directory responses.
|
||||||
var response = request.response;
|
var response = request.response;
|
||||||
response.headers
|
response.headers
|
||||||
.set("Cache-Control", "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
|
.set("Cache-Control", "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
|
||||||
var path = _getFilePathFromRequestPath(request.uri.path);
|
var path = _getFileUriFromRequestUri(request.uri);
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
var file = new File(path.toNativePath());
|
var file = new File.fromUri(path);
|
||||||
file.exists().then((exists) {
|
var directory = new Directory.fromUri(path);
|
||||||
if (exists) {
|
if (await file.exists()){
|
||||||
_sendFileContent(request, response, allowedPort, path, file);
|
_sendFileContent(request, response, allowedPort, file);
|
||||||
} else {
|
} else if (await directory.exists()) {
|
||||||
var directory = new Directory(path.toNativePath());
|
_sendDirectoryListing(
|
||||||
directory.exists().then((exists) {
|
await _listDirectory(directory), request, response);
|
||||||
if (exists) {
|
} else {
|
||||||
_listDirectory(directory).then((entries) {
|
_sendNotFound(request);
|
||||||
_sendDirectoryListing(entries, request, response);
|
}
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_sendNotFound(request);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
if (request.uri.path == '/') {
|
if (request.uri.path == '/') {
|
||||||
var entries = [
|
var entries = [
|
||||||
|
@ -277,33 +288,21 @@ class TestingServers {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Path _getFilePathFromRequestPath(String urlRequestPath) {
|
Uri _getFileUriFromRequestUri(Uri request) {
|
||||||
// Go to the top of the file to see an explanation of the URL path scheme.
|
// Go to the top of the file to see an explanation of the URL path scheme.
|
||||||
var requestPath = new Path(urlRequestPath.substring(1)).canonicalize();
|
List<String> pathSegments = request.normalizePath().pathSegments;
|
||||||
var pathSegments = requestPath.segments();
|
if (pathSegments.length == 0) return null;
|
||||||
if (pathSegments.length > 0) {
|
int packagesIndex = pathSegments.indexOf('packages');
|
||||||
var basePath;
|
if (packagesIndex != -1) {
|
||||||
var relativePath;
|
var packageUri = new Uri(scheme: 'package',
|
||||||
if (pathSegments[0] == PREFIX_BUILDDIR) {
|
pathSegments: pathSegments.skip(packagesIndex + 1));
|
||||||
basePath = _buildDirectory;
|
return _resolver.resolveUri(packageUri);
|
||||||
relativePath = new Path(pathSegments.skip(1).join('/'));
|
}
|
||||||
} else if (pathSegments[0] == PREFIX_DARTDIR) {
|
if (pathSegments[0] == PREFIX_BUILDDIR) {
|
||||||
basePath = _dartDirectory;
|
return _buildDirectory.resolve(pathSegments.skip(1).join('/'));
|
||||||
relativePath = new Path(pathSegments.skip(1).join('/'));
|
}
|
||||||
}
|
if (pathSegments[0] == PREFIX_DARTDIR) {
|
||||||
var packagesIndex = pathSegments.indexOf('packages');
|
return _dartDirectory.resolve(pathSegments.skip(1).join('/'));
|
||||||
if (packagesIndex != -1) {
|
|
||||||
if (_packages != null) {
|
|
||||||
// TODO(27065): Package spec file not supported by http server yet
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
var start = packagesIndex + 1;
|
|
||||||
basePath = _packageRoot;
|
|
||||||
relativePath = new Path(pathSegments.skip(start).join('/'));
|
|
||||||
}
|
|
||||||
if (basePath != null && relativePath != null) {
|
|
||||||
return basePath.join(relativePath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -313,11 +312,13 @@ class TestingServers {
|
||||||
var entries = [];
|
var entries = [];
|
||||||
|
|
||||||
directory.list().listen((FileSystemEntity fse) {
|
directory.list().listen((FileSystemEntity fse) {
|
||||||
var filename = new Path(fse.path).filename;
|
var segments = fse.uri.pathSegments;
|
||||||
if (fse is File) {
|
if (fse is File) {
|
||||||
|
var filename = segments.last;
|
||||||
entries.add(new _Entry(filename, filename));
|
entries.add(new _Entry(filename, filename));
|
||||||
} else if (fse is Directory) {
|
} else if (fse is Directory) {
|
||||||
entries.add(new _Entry(filename, '$filename/'));
|
var dirname = segments[segments.length - 2];
|
||||||
|
entries.add(new _Entry(dirname, '$dirname/'));
|
||||||
}
|
}
|
||||||
}, onDone: () {
|
}, onDone: () {
|
||||||
completer.complete(entries);
|
completer.complete(entries);
|
||||||
|
@ -348,7 +349,7 @@ class TestingServers {
|
||||||
response.write(header);
|
response.write(header);
|
||||||
for (var entry in entries) {
|
for (var entry in entries) {
|
||||||
response.write(
|
response.write(
|
||||||
'<li><a href="${new Path(request.uri.path).append(entry.name)}">'
|
'<li><a href="${request.uri}/${entry.name}">'
|
||||||
'${entry.displayName}</a></li>');
|
'${entry.displayName}</a></li>');
|
||||||
}
|
}
|
||||||
response.write(footer);
|
response.write(footer);
|
||||||
|
@ -360,7 +361,7 @@ class TestingServers {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _sendFileContent(HttpRequest request, HttpResponse response,
|
void _sendFileContent(HttpRequest request, HttpResponse response,
|
||||||
int allowedPort, Path path, File file) {
|
int allowedPort, File file) {
|
||||||
if (allowedPort != -1) {
|
if (allowedPort != -1) {
|
||||||
var headerOrigin = request.headers.value('Origin');
|
var headerOrigin = request.headers.value('Origin');
|
||||||
var allowedOrigin;
|
var allowedOrigin;
|
||||||
|
@ -396,15 +397,15 @@ class TestingServers {
|
||||||
response.headers.set("X-WebKit-CSP", content_header_value);
|
response.headers.set("X-WebKit-CSP", content_header_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (path.filename.endsWith('.html')) {
|
if (file.path.endsWith('.html')) {
|
||||||
response.headers.set('Content-Type', 'text/html');
|
response.headers.set('Content-Type', 'text/html');
|
||||||
} else if (path.filename.endsWith('.js')) {
|
} else if (file.path.endsWith('.js')) {
|
||||||
response.headers.set('Content-Type', 'application/javascript');
|
response.headers.set('Content-Type', 'application/javascript');
|
||||||
} else if (path.filename.endsWith('.dart')) {
|
} else if (file.path.endsWith('.dart')) {
|
||||||
response.headers.set('Content-Type', 'application/dart');
|
response.headers.set('Content-Type', 'application/dart');
|
||||||
} else if (path.filename.endsWith('.css')) {
|
} else if (file.path.endsWith('.css')) {
|
||||||
response.headers.set('Content-Type', 'text/css');
|
response.headers.set('Content-Type', 'text/css');
|
||||||
} else if (path.filename.endsWith('.xml')) {
|
} else if (file.path.endsWith('.xml')) {
|
||||||
response.headers.set('Content-Type', 'text/xml');
|
response.headers.set('Content-Type', 'text/xml');
|
||||||
}
|
}
|
||||||
response.headers.removeAll("X-Frame-Options");
|
response.headers.removeAll("X-Frame-Options");
|
||||||
|
|
|
@ -132,11 +132,12 @@ Future testConfigurations(List<Map> configurations) async {
|
||||||
// server for cross-domain tests can be found by calling
|
// server for cross-domain tests can be found by calling
|
||||||
// getCrossOriginPortNumber().
|
// getCrossOriginPortNumber().
|
||||||
var servers = new TestingServers(
|
var servers = new TestingServers(
|
||||||
new Path(TestUtils.buildDir(conf)),
|
TestUtils.buildDir(conf),
|
||||||
useContentSecurityPolicy,
|
useContentSecurityPolicy,
|
||||||
conf['runtime'],
|
conf['runtime'],
|
||||||
null,
|
null,
|
||||||
conf['package_root']);
|
conf['package_root'],
|
||||||
|
conf['packages']);
|
||||||
serverFutures.add(servers.startServers(conf['local_ip'],
|
serverFutures.add(servers.startServers(conf['local_ip'],
|
||||||
port: conf['test_server_port'],
|
port: conf['test_server_port'],
|
||||||
crossOriginPort: conf['test_server_cross_origin_port']));
|
crossOriginPort: conf['test_server_cross_origin_port']));
|
||||||
|
|
Loading…
Reference in a new issue