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 |
| index 6ce667b687dfbb97f858d13d2acb69f91e1801a6..2e684ec7e281876346f1e087e0492da2b14456d2 100644 |
| --- a/pkg/http_server/lib/src/virtual_directory.dart |
| +++ b/pkg/http_server/lib/src/virtual_directory.dart |
| @@ -81,6 +81,8 @@ class _VirtualDirectory implements VirtualDirectory { |
| } |
| if (entity is File) { |
| _serveFile(entity, request); |
| + } else if (entity is Directory) { |
| + _serveDirectory(entity, request); |
| } else { |
| _serveErrorPage(HttpStatus.NOT_FOUND, request); |
| } |
| @@ -122,6 +124,9 @@ class _VirtualDirectory implements VirtualDirectory { |
| .canonicalize(); |
| if (targetPath.segments().isEmpty || |
| targetPath.segments().first == '..') return null; |
| + if (segments.isEmpty) { |
| + return _locateResource(targetPath, []); |
| + } |
| return _locateResource(targetPath.append(segments.first), |
| segments.skip(1)); |
| }); |
| @@ -197,6 +202,81 @@ class _VirtualDirectory implements VirtualDirectory { |
| }); |
| } |
| + void _serveDirectory(Directory dir, HttpRequest request) { |
|
Søren Gjesse
2013/06/26 10:19:11
Maybe add a callback for the directory page as we
|
| + var response = request.response; |
| + dir.stat().then((stats) { |
| + if (request.headers.ifModifiedSince != null && |
| + !stats.modified.isAfter(request.headers.ifModifiedSince)) { |
| + response.statusCode = HttpStatus.NOT_MODIFIED; |
| + response.close(); |
| + return; |
| + } |
| + |
| + response.headers.set(HttpHeaders.LAST_MODIFIED, stats.modified); |
| + var path = request.uri.path; |
| + var header = |
| +'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
| +http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| +<html xmlns="http://www.w3.org/1999/xhtml"> |
| +<head> |
| +<title>Index of $path</title> |
| +</head> |
| +<body> |
| +<h1>Index of $path</h1> |
| +<table> |
| + <tr> |
| + <td>Name</td> |
| + <td>Last modified</td> |
| + <td>Size</td> |
| + </tr> |
| +'''; |
| + var server = response.headers.value(HttpHeaders.SERVER); |
| + if (server == null) server = ""; |
| + var footer = |
| +'''</table> |
| +$server |
| +</body> |
| +</html> |
| +'''; |
| + |
| + response.write(header); |
| + |
| + void add(String name, DateTime modified, var size) { |
| + if (size == null) size = "-"; |
| + if (modified == null) modified = ""; |
| + var p = new Path(path).append(name).canonicalize().toString(); |
| + var entry = |
| +''' <tr> |
| + <td><a href="$p">$name</a></td> |
| + <td>$modified</td> |
| + <td style="text-align: right">$size</td> |
| + </tr>'''; |
| + response.write(entry); |
| + } |
| + |
| + if (path != '/') { |
| + add('../', null, null); |
| + } |
| + |
| + dir.list(followLinks: true).listen((entity) { |
| + // TODO(ajohnsen): Consider async dir listing. |
| + if (entity is File) { |
| + add(new Path(entity.path).filename, |
| + entity.statSync().modified, |
| + entity.lengthSync()); |
| + } else if (entity is Directory) { |
| + add(new Path(entity.path).filename + '/', |
| + entity.statSync().modified, |
| + null); |
| + } |
| + }, onError: (e) { |
| + }, onDone: () { |
| + response.write(footer); |
| + response.close(); |
| + }); |
| + }, onError: (e) => response.close()); |
| + } |
| + |
| void _serveErrorPage(int error, HttpRequest request) { |
| var response = request.response; |
| response.statusCode = error; |
| @@ -207,22 +287,22 @@ class _VirtualDirectory implements VirtualDirectory { |
| // Default error page. |
| var path = request.uri.path; |
| var reason = response.reasonPhrase; |
| - response.write( |
| - '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n'); |
| - response.writeln( |
| - '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'); |
| - response.writeln('<html xmlns="http://www.w3.org/1999/xhtml">'); |
| - response.writeln('<head>'); |
| - response.writeln('<title>$reason: $path</title>'); |
| - response.writeln('</head>'); |
| - response.writeln('<body>'); |
| - response.writeln('<h1>Error $error at \'$path\': $reason</h1>'); |
| + |
| var server = response.headers.value(HttpHeaders.SERVER); |
| - if (server != null) { |
| - response.writeln(server); |
| - } |
| - response.writeln('</body>'); |
| - response.writeln('</html>'); |
| + if (server == null) server = ""; |
| + var page = |
| +'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
| +http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| +<html xmlns="http://www.w3.org/1999/xhtml"> |
| +<head> |
| +<title>$reason: $path</title> |
| +</head> |
| +<body> |
| +<h1>Error $error at \'$path\': $reason</h1> |
| +$server |
| +</body> |
| +</html>'''; |
| + response.write(page); |
| response.close(); |
| } |
| } |