Chromium Code Reviews| Index: pkg/http_server/lib/src/virtual_directory.dart |
| diff --git a/pkg/http_server/lib/src/virtual_directory.dart b/pkg/http_server/lib/src/virtual_directory.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..334fba1fdb02965f3252f0f2644e3c94ac77ed08 |
| --- /dev/null |
| +++ b/pkg/http_server/lib/src/virtual_directory.dart |
| @@ -0,0 +1,113 @@ |
| +// 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. |
| + |
| +part of http_server; |
| + |
| +/** |
| + * A [VirtualDirectory] can serve files and directory-listing from a root path, |
| + * to [HttpRequest]s. |
| + * |
| + * The [VirtualDirectory] providing secure handling of request uris and |
| + * file-system links, correct mime-types and custom error pages. |
| + */ |
| +abstract class VirtualDirectory { |
| + final String root; |
| + |
| + /** |
| + * Set or get if the [VirtualDirectory] should list the content of |
| + * directories. |
| + */ |
| + bool allowDirectoryListing = false; |
| + |
| + /** |
| + * Set or get if the [VirtualDirectory] should follow links, that point |
| + * to other resources within the [root] directory. |
| + */ |
| + bool followLinks = true; |
| + |
| + /* |
| + * Create a new [VirtualDirectory] for serving static file content of |
| + * the path [root]. |
| + * |
| + * The [root] is not required to exist. If the [root] doesn't exist at time of |
| + * a request, a 404 is generated. |
| + */ |
| + factory VirtualDirectory(String root) => new _VirtualDirectory(root); |
| + |
|
Søren Gjesse
2013/06/21 11:17:23
Dartdoc for serve and serveRequest
Anders Johnsen
2013/06/21 11:22:28
Done.
|
| + void serve(Stream<HttpRequest> requests); |
| + |
| + void serveRequest(HttpRequest request); |
| + |
| + /** |
| + * Set the [callback] to override the error page handler. When [callback] is |
| + * invoked, the [response] have the [HttpResponse.statusCode] set accordingly. |
|
Søren Gjesse
2013/06/21 11:17:23
"the [response] have the [HttpResponse.statusCode]
Anders Johnsen
2013/06/21 11:22:28
Done.
|
| + */ |
| + void setErrorPageHandler(void callback(HttpResponse response)); |
| +} |
| + |
| +class _VirtualDirectory implements VirtualDirectory { |
| + final String root; |
| + |
| + bool _allowDirectoryListing = false; |
| + bool _followLinks = true; |
| + |
| + _VirtualDirectory(this.root); |
| + |
| + void serve(Stream<HttpRequest> requests) { |
| + requests.listen(serveRequest); |
| + } |
| + |
| + void serveRequest(HttpRequest request) { |
| + var path = new Path(request.uri.path).canonicalize(); |
| + |
| + if (!path.isAbsolute) { |
|
Søren Gjesse
2013/06/21 11:17:23
Use HttpStatus constants
Anders Johnsen
2013/06/21 11:22:28
Done.
|
| + return _serveErrorPage(404, request); |
| + } |
| + |
| + _locateResource(new Path(root), path.segments()) |
| + .then((entity) { |
| + if (entity == null) return _serveErrorPage(404, request); |
| + if (entity is File) { |
| + entity.openRead().pipe(request.response).catchError((_) {}); |
| + } else { |
| + return _serveErrorPage(404, request); |
| + } |
| + print(entity); |
| + }); |
| + } |
| + |
| + Future<FileSystemEntity> _locateResource(Path path, |
| + Iterable<String> segments) { |
| + return FileSystemEntity.type(path.toString(), followLinks: false) |
| + .then((type) { |
| + switch (type) { |
| + case FileSystemEntityType.FILE: |
| + if (segments.isEmpty) return new File.fromPath(path); |
| + break; |
| + |
| + case FileSystemEntityType.DIRECTORY: |
| + if (segments.isEmpty) { |
| + if (_allowDirectoryListing) return new Directory.fromPath(path); |
| + } else { |
| + return _locateResource(path.append(segments.first), |
| + segments.skip(1)); |
| + } |
| + break; |
| + |
| + case FileSystemEntityType.LINK: |
| + if (followLinks) { |
| + // TODO |
| + } |
| + break; |
| + |
| + } |
|
Søren Gjesse
2013/06/21 11:17:23
Comment on fall-through.
Anders Johnsen
2013/06/21 11:22:28
Done.
|
| + return null; |
| + }); |
| + } |
| + |
| + void _serveErrorPage(int error, HttpRequest request) { |
| + request.response.statusCode = 404; |
| + request.response.close(); |
| + } |
| +} |