OLD | NEW |
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 Function _errorCallback; | 70 Function _errorCallback; |
71 Function _dirCallback; | 71 Function _dirCallback; |
72 | 72 |
73 _VirtualDirectory(this.root); | 73 _VirtualDirectory(this.root); |
74 | 74 |
75 void serve(Stream<HttpRequest> requests) { | 75 void serve(Stream<HttpRequest> requests) { |
76 requests.listen(serveRequest); | 76 requests.listen(serveRequest); |
77 } | 77 } |
78 | 78 |
79 void serveRequest(HttpRequest request) { | 79 void serveRequest(HttpRequest request) { |
80 _locateResource(new Path('.'), request.uri.pathSegments.iterator..moveNext()
) | 80 _locateResource('.', request.uri.pathSegments.iterator..moveNext()) |
81 .then((entity) { | 81 .then((entity) { |
82 if (entity == null) { | 82 if (entity == null) { |
83 _serveErrorPage(HttpStatus.NOT_FOUND, request); | 83 _serveErrorPage(HttpStatus.NOT_FOUND, request); |
84 return; | 84 return; |
85 } | 85 } |
86 if (entity is File) { | 86 if (entity is File) { |
87 _serveFile(entity, request); | 87 _serveFile(entity, request); |
88 } else if (entity is Directory) { | 88 } else if (entity is Directory) { |
89 _serveDirectory(entity, request); | 89 _serveDirectory(entity, request); |
90 } else { | 90 } else { |
91 _serveErrorPage(HttpStatus.NOT_FOUND, request); | 91 _serveErrorPage(HttpStatus.NOT_FOUND, request); |
92 } | 92 } |
93 }); | 93 }); |
94 } | 94 } |
95 | 95 |
96 void setDirectoryHandler(void callback(Directory dir, HttpRequest request)) { | 96 void setDirectoryHandler(void callback(Directory dir, HttpRequest request)) { |
97 _dirCallback = callback; | 97 _dirCallback = callback; |
98 } | 98 } |
99 | 99 |
100 void setErrorPageHandler(void callback(HttpRequest request)) { | 100 void setErrorPageHandler(void callback(HttpRequest request)) { |
101 _errorCallback = callback; | 101 _errorCallback = callback; |
102 } | 102 } |
103 | 103 |
104 Future<FileSystemEntity> _locateResource(Path path, | 104 Future<FileSystemEntity> _locateResource(String path, |
105 Iterator<String> segments) { | 105 Iterator<String> segments) { |
106 path = path.canonicalize(); | 106 path = normalize(path); |
107 if (path.segments().first == "..") return new Future.value(null); | 107 if (split(path).first == "..") return new Future.value(null); |
108 Path fullPath() => new Path(root).join(path); | 108 String fullPath() => join(root, path); |
109 return FileSystemEntity.type(fullPath().toNativePath(), followLinks: false) | 109 return FileSystemEntity.type(fullPath(), followLinks: false) |
110 .then((type) { | 110 .then((type) { |
111 switch (type) { | 111 switch (type) { |
112 case FileSystemEntityType.FILE: | 112 case FileSystemEntityType.FILE: |
113 if (segments.current == null) { | 113 if (segments.current == null) { |
114 return new File.fromPath(fullPath()); | 114 return new File(fullPath()); |
115 } | 115 } |
116 break; | 116 break; |
117 | 117 |
118 case FileSystemEntityType.DIRECTORY: | 118 case FileSystemEntityType.DIRECTORY: |
119 if (segments.current == null) { | 119 if (segments.current == null) { |
120 if (allowDirectoryListing) { | 120 if (allowDirectoryListing) { |
121 return new Directory.fromPath(fullPath()); | 121 return new Directory(fullPath()); |
122 } | 122 } |
123 } else { | 123 } else { |
124 if (_invalidPathRegExp.hasMatch(segments.current)) break; | 124 if (_invalidPathRegExp.hasMatch(segments.current)) break; |
125 return _locateResource(path.append(segments.current), | 125 return _locateResource(join(path, segments.current), |
126 segments..moveNext()); | 126 segments..moveNext()); |
127 } | 127 } |
128 break; | 128 break; |
129 | 129 |
130 case FileSystemEntityType.LINK: | 130 case FileSystemEntityType.LINK: |
131 if (followLinks) { | 131 if (followLinks) { |
132 return new Link.fromPath(fullPath()).target() | 132 return new Link(fullPath()).target() |
133 .then((target) { | 133 .then((target) { |
134 var targetPath = new Path(target).canonicalize(); | 134 String targetPath = normalize(target); |
135 if (targetPath.isAbsolute) return null; | 135 if (isAbsolute(targetPath)) return null; |
136 targetPath = path.directoryPath.join(targetPath); | 136 targetPath = join(dirname(path), targetPath); |
137 return _locateResource(targetPath, segments); | 137 return _locateResource(targetPath, segments); |
138 }); | 138 }); |
139 } | 139 } |
140 break; | 140 break; |
141 } | 141 } |
142 // Return `null` on fall-through, to indicate NOT_FOUND. | 142 // Return `null` on fall-through, to indicate NOT_FOUND. |
143 return null; | 143 return null; |
144 }); | 144 }); |
145 } | 145 } |
146 | 146 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 $server | 247 $server |
248 </body> | 248 </body> |
249 </html> | 249 </html> |
250 '''; | 250 '''; |
251 | 251 |
252 response.write(header); | 252 response.write(header); |
253 | 253 |
254 void add(String name, String modified, var size) { | 254 void add(String name, String modified, var size) { |
255 if (size == null) size = "-"; | 255 if (size == null) size = "-"; |
256 if (modified == null) modified = ""; | 256 if (modified == null) modified = ""; |
257 var p = new Path(path).append(name).canonicalize().toString(); | 257 var p = normalize(join(path, name)); |
258 var entry = | 258 var entry = |
259 ''' <tr> | 259 ''' <tr> |
260 <td><a href="$p">$name</a></td> | 260 <td><a href="$p">$name</a></td> |
261 <td>$modified</td> | 261 <td>$modified</td> |
262 <td style="text-align: right">$size</td> | 262 <td style="text-align: right">$size</td> |
263 </tr>'''; | 263 </tr>'''; |
264 response.write(entry); | 264 response.write(entry); |
265 } | 265 } |
266 | 266 |
267 if (path != '/') { | 267 if (path != '/') { |
268 add('../', null, null); | 268 add('../', null, null); |
269 } | 269 } |
270 | 270 |
271 dir.list(followLinks: true).listen((entity) { | 271 dir.list(followLinks: true).listen((entity) { |
272 // TODO(ajohnsen): Consider async dir listing. | 272 // TODO(ajohnsen): Consider async dir listing. |
273 if (entity is File) { | 273 if (entity is File) { |
274 var stat = entity.statSync(); | 274 var stat = entity.statSync(); |
275 add(new Path(entity.path).filename, | 275 add(basename(entity.path), |
276 stat.modified.toString(), | 276 stat.modified.toString(), |
277 stat.size); | 277 stat.size); |
278 } else if (entity is Directory) { | 278 } else if (entity is Directory) { |
279 add(new Path(entity.path).filename + '/', | 279 add(basename(entity.path) + '/', |
280 entity.statSync().modified.toString(), | 280 entity.statSync().modified.toString(), |
281 null); | 281 null); |
282 } | 282 } |
283 }, onError: (e) { | 283 }, onError: (e) { |
284 }, onDone: () { | 284 }, onDone: () { |
285 response.write(footer); | 285 response.write(footer); |
286 response.close(); | 286 response.close(); |
287 }); | 287 }); |
288 }, onError: (e) => response.close()); | 288 }, onError: (e) => response.close()); |
289 } | 289 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 | 366 |
367 Future close() => new Future.value(); | 367 Future close() => new Future.value(); |
368 | 368 |
369 void setMimeType(var bytes) { | 369 void setMimeType(var bytes) { |
370 var mimeType = lookupMimeType(path, headerBytes: bytes); | 370 var mimeType = lookupMimeType(path, headerBytes: bytes); |
371 if (mimeType != null) { | 371 if (mimeType != null) { |
372 response.headers.contentType = ContentType.parse(mimeType); | 372 response.headers.contentType = ContentType.parse(mimeType); |
373 } | 373 } |
374 } | 374 } |
375 } | 375 } |
OLD | NEW |