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

Side by Side Diff: pkg/http_server/lib/src/virtual_directory.dart

Issue 17582007: Add support for following links, in VirtualDirectory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of http_server; 5 part of http_server;
6 6
7 /** 7 /**
8 * A [VirtualDirectory] can serve files and directory-listing from a root path, 8 * A [VirtualDirectory] can serve files and directory-listing from a root path,
9 * to [HttpRequest]s. 9 * to [HttpRequest]s.
10 * 10 *
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 /** 48 /**
49 * Set the [callback] to override the error page handler. When [callback] is 49 * Set the [callback] to override the error page handler. When [callback] is
50 * invoked, the `statusCode` property of the response is set. 50 * invoked, the `statusCode` property of the response is set.
51 */ 51 */
52 void setErrorPageHandler(void callback(HttpResponse response)); 52 void setErrorPageHandler(void callback(HttpResponse response));
53 } 53 }
54 54
55 class _VirtualDirectory implements VirtualDirectory { 55 class _VirtualDirectory implements VirtualDirectory {
56 final String root; 56 final String root;
57 57
58 bool _allowDirectoryListing = false; 58 bool allowDirectoryListing = false;
59 bool _followLinks = true; 59 bool followLinks = true;
60 60
61 _VirtualDirectory(this.root); 61 _VirtualDirectory(this.root);
62 62
63 void serve(Stream<HttpRequest> requests) { 63 void serve(Stream<HttpRequest> requests) {
64 requests.listen(serveRequest); 64 requests.listen(serveRequest);
65 } 65 }
66 66
67 void serveRequest(HttpRequest request) { 67 void serveRequest(HttpRequest request) {
68 var path = new Path(request.uri.path).canonicalize(); 68 var path = new Path(request.uri.path).canonicalize();
69 69
70 if (!path.isAbsolute) { 70 if (!path.isAbsolute) {
71 return _serveErrorPage(HttpStatus.NOT_FOUND, request); 71 return _serveErrorPage(HttpStatus.NOT_FOUND, request);
72 } 72 }
73 73
74 _locateResource(new Path(root), path.segments()) 74 _locateResource(new Path('.'), path.segments())
75 .then((entity) { 75 .then((entity) {
76 if (entity == null) { 76 if (entity == null) {
77 _serveErrorPage(HttpStatus.NOT_FOUND, request); 77 _serveErrorPage(HttpStatus.NOT_FOUND, request);
78 return; 78 return;
79 } 79 }
80 if (entity is File) { 80 if (entity is File) {
81 entity.openRead().pipe(request.response).catchError((_) {}); 81 entity.openRead().pipe(request.response).catchError((_) {});
82 } else { 82 } else {
83 _serveErrorPage(HttpStatus.NOT_FOUND, request); 83 _serveErrorPage(HttpStatus.NOT_FOUND, request);
84 } 84 }
85 }); 85 });
86 } 86 }
87 87
88 Future<FileSystemEntity> _locateResource(Path path, 88 Future<FileSystemEntity> _locateResource(Path path,
89 Iterable<String> segments) { 89 Iterable<String> segments) {
90 return FileSystemEntity.type(path.toNativePath(), followLinks: false) 90 Path fullPath() => new Path(root).join(path);
91 return FileSystemEntity.type(fullPath().toNativePath(), followLinks: false)
91 .then((type) { 92 .then((type) {
92 switch (type) { 93 switch (type) {
93 case FileSystemEntityType.FILE: 94 case FileSystemEntityType.FILE:
94 if (segments.isEmpty) return new File.fromPath(path); 95 if (segments.isEmpty) return new File.fromPath(fullPath());
95 break; 96 break;
96 97
97 case FileSystemEntityType.DIRECTORY: 98 case FileSystemEntityType.DIRECTORY:
98 if (segments.isEmpty) { 99 if (segments.isEmpty) {
99 if (_allowDirectoryListing) return new Directory.fromPath(path); 100 if (allowDirectoryListing) {
101 return new Directory.fromPath(fullPath());
102 }
100 } else { 103 } else {
101 return _locateResource(path.append(segments.first), 104 return _locateResource(path.append(segments.first),
102 segments.skip(1)); 105 segments.skip(1));
103 } 106 }
104 break; 107 break;
105 108
106 case FileSystemEntityType.LINK: 109 case FileSystemEntityType.LINK:
107 if (followLinks) { 110 if (followLinks) {
108 // TODO 111 return new Link.fromPath(fullPath()).target()
112 .then((target) {
113 var targetPath = new Path(target).canonicalize();
114 if (targetPath.isAbsolute) return null;
115 targetPath = path.append('..').join(targetPath)
Søren Gjesse 2013/06/24 08:08:53 Why do you need this additional ..?
Anders Johnsen 2013/06/24 08:21:16 To 'pop' the link. Changed to use path.directoryPa
116 .canonicalize();
117 if (targetPath.segments().isEmpty ||
118 targetPath.segments().first == '..') return null;
119 return _locateResource(targetPath.append(segments.first),
120 segments.skip(1));
121 });
109 } 122 }
110 break; 123 break;
111 } 124 }
112 // Return `null` on fall-through, to indicate NOT_FOUND. 125 // Return `null` on fall-through, to indicate NOT_FOUND.
113 return null; 126 return null;
114 }); 127 });
115 } 128 }
116 129
117 void _serveErrorPage(int error, HttpRequest request) { 130 void _serveErrorPage(int error, HttpRequest request) {
118 request.response.statusCode = error; 131 request.response.statusCode = error;
119 request.response.close(); 132 request.response.close();
120 } 133 }
121 } 134 }
OLDNEW
« no previous file with comments | « no previous file | pkg/http_server/test/virtual_directory_test.dart » ('j') | pkg/http_server/test/virtual_directory_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698