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

Unified Diff: pkg/http_server/lib/src/virtual_directory.dart

Issue 17544005: First push of a new 'http_server' dart package. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Review changes. Created 7 years, 6 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 | « pkg/http_server/lib/http_server.dart ('k') | pkg/http_server/pubspec.yaml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..a09613527008cdebc12d9ea51a3f1192fe9c0cbd
--- /dev/null
+++ b/pkg/http_server/lib/src/virtual_directory.dart
@@ -0,0 +1,122 @@
+// 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);
+
+ /**
+ * Serve a [Stream] of [HttpRequest]s, in this [VirtualDirectory].
+ */
+ void serve(Stream<HttpRequest> requests);
+
+ /**
+ * Serve a single [HttpRequest], in this [VirtualDirectory].
+ */
+ void serveRequest(HttpRequest request);
+
+ /**
+ * Set the [callback] to override the error page handler. When [callback] is
+ * invoked, the `statusCode` property of the response is set.
+ */
+ 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) {
+ return _serveErrorPage(HttpStatus.NOT_FOUND, request);
+ }
+
+ _locateResource(new Path(root), path.segments())
+ .then((entity) {
+ if (entity == null) {
+ _serveErrorPage(HttpStatus.NOT_FOUND, request);
+ return;
+ }
+ if (entity is File) {
+ entity.openRead().pipe(request.response).catchError((_) {});
+ } else {
+ _serveErrorPage(HttpStatus.NOT_FOUND, request);
+ }
+ });
+ }
+
+ 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;
+
+ }
+ // Return `null` on fall-through, to indicate NOT_FOUND.
+ return null;
+ });
+ }
+
+ void _serveErrorPage(int error, HttpRequest request) {
+ request.response.statusCode = error;
+ request.response.close();
+ }
+}
« no previous file with comments | « pkg/http_server/lib/http_server.dart ('k') | pkg/http_server/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698