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

Unified Diff: mojo/public/dart/third_party/shelf_static/lib/src/static_handler.dart

Issue 1346773002: Stop running pub get at gclient sync time and fix build bugs (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 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
Index: mojo/public/dart/third_party/shelf_static/lib/src/static_handler.dart
diff --git a/mojo/public/dart/third_party/shelf_static/lib/src/static_handler.dart b/mojo/public/dart/third_party/shelf_static/lib/src/static_handler.dart
new file mode 100644
index 0000000000000000000000000000000000000000..c0afeb4246dfd7732e385ac1ff5da79910caf416
--- /dev/null
+++ b/mojo/public/dart/third_party/shelf_static/lib/src/static_handler.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2015, 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 shelf_static.static_handler;
+
+import 'dart:io';
+
+import 'package:http_parser/http_parser.dart';
+import 'package:mime/mime.dart' as mime;
+import 'package:path/path.dart' as p;
+import 'package:shelf/shelf.dart';
+
+import 'directory_listing.dart';
+import 'util.dart';
+
+// TODO option to exclude hidden files?
+
+/// Creates a Shelf [Handler] that serves files from the provided
+/// [fileSystemPath].
+///
+/// Accessing a path containing symbolic links will succeed only if the resolved
+/// path is within [fileSystemPath]. To allow access to paths outside of
+/// [fileSystemPath], set [serveFilesOutsidePath] to `true`.
+///
+/// When a existing directory is requested and a [defaultDocument] is specified
+/// the directory is checked for a file with that name. If it exists, it is
+/// served.
+///
+/// If no [defaultDocument] is found and [listDirectories] is true, then the
+/// handler produces a listing of the directory.
+Handler createStaticHandler(String fileSystemPath,
+ {bool serveFilesOutsidePath: false, String defaultDocument,
+ bool listDirectories: false}) {
+ var rootDir = new Directory(fileSystemPath);
+ if (!rootDir.existsSync()) {
+ throw new ArgumentError('A directory corresponding to fileSystemPath '
+ '"$fileSystemPath" could not be found');
+ }
+
+ fileSystemPath = rootDir.resolveSymbolicLinksSync();
+
+ if (defaultDocument != null) {
+ if (defaultDocument != p.basename(defaultDocument)) {
+ throw new ArgumentError('defaultDocument must be a file name.');
+ }
+ }
+
+ return (Request request) {
+ var segs = [fileSystemPath]..addAll(request.url.pathSegments);
+
+ var fsPath = p.joinAll(segs);
+
+ var entityType = FileSystemEntity.typeSync(fsPath, followLinks: true);
+
+ File file = null;
+
+ if (entityType == FileSystemEntityType.FILE) {
+ file = new File(fsPath);
+ } else if (entityType == FileSystemEntityType.DIRECTORY) {
+ file = _tryDefaultFile(fsPath, defaultDocument);
+ if (file == null && listDirectories) {
+ var uri = request.requestedUri;
+ if (!uri.path.endsWith('/')) return _redirectToAddTrailingSlash(uri);
+ return listDirectory(fileSystemPath, fsPath);
+ }
+ }
+
+ if (file == null) {
+ return new Response.notFound('Not Found');
+ }
+
+ if (!serveFilesOutsidePath) {
+ var resolvedPath = file.resolveSymbolicLinksSync();
+
+ // Do not serve a file outside of the original fileSystemPath
+ if (!p.isWithin(fileSystemPath, resolvedPath)) {
+ return new Response.notFound('Not Found');
+ }
+ }
+
+ // when serving the default document for a directory, if the requested
+ // path doesn't end with '/', redirect to the path with a trailing '/'
+ var uri = request.requestedUri;
+ if (entityType == FileSystemEntityType.DIRECTORY &&
+ !uri.path.endsWith('/')) {
+ return _redirectToAddTrailingSlash(uri);
+ }
+
+ var fileStat = file.statSync();
+ var ifModifiedSince = request.ifModifiedSince;
+
+ if (ifModifiedSince != null) {
+ var fileChangeAtSecResolution = toSecondResolution(fileStat.changed);
+ if (!fileChangeAtSecResolution.isAfter(ifModifiedSince)) {
+ return new Response.notModified();
+ }
+ }
+
+ var headers = <String, String>{
+ HttpHeaders.CONTENT_LENGTH: fileStat.size.toString(),
+ HttpHeaders.LAST_MODIFIED: formatHttpDate(fileStat.changed)
+ };
+
+ var contentType = mime.lookupMimeType(file.path);
+ if (contentType != null) {
+ headers[HttpHeaders.CONTENT_TYPE] = contentType;
+ }
+
+ return new Response.ok(file.openRead(), headers: headers);
+ };
+}
+
+Response _redirectToAddTrailingSlash(Uri uri) {
+ var location = new Uri(
+ scheme: uri.scheme,
+ userInfo: uri.userInfo,
+ host: uri.host,
+ port: uri.port,
+ path: uri.path + '/',
+ query: uri.query);
+
+ return new Response.movedPermanently(location.toString());
+}
+
+File _tryDefaultFile(String dirPath, String defaultFile) {
+ if (defaultFile == null) return null;
+
+ var filePath = p.join(dirPath, defaultFile);
+
+ var file = new File(filePath);
+
+ if (file.existsSync()) {
+ return file;
+ }
+
+ return null;
+}

Powered by Google App Engine
This is Rietveld 408576698