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

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

Issue 18333003: Correctly url-decode the path segment in the http_server. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add another test. 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 Function _errorCallback; 68 Function _errorCallback;
69 Function _dirCallback; 69 Function _dirCallback;
70 70
71 _VirtualDirectory(this.root); 71 _VirtualDirectory(this.root);
72 72
73 void serve(Stream<HttpRequest> requests) { 73 void serve(Stream<HttpRequest> requests) {
74 requests.listen(serveRequest); 74 requests.listen(serveRequest);
75 } 75 }
76 76
77 void serveRequest(HttpRequest request) { 77 void serveRequest(HttpRequest request) {
78 var path = new Path(request.uri.path).canonicalize(); 78 _locateResource(new Path('.'), request.uri.pathSegments)
79
80 if (!path.isAbsolute) {
81 return _serveErrorPage(HttpStatus.NOT_FOUND, request);
82 }
83
84 _locateResource(new Path('.'), path.segments())
85 .then((entity) { 79 .then((entity) {
86 if (entity == null) { 80 if (entity == null) {
87 _serveErrorPage(HttpStatus.NOT_FOUND, request); 81 _serveErrorPage(HttpStatus.NOT_FOUND, request);
88 return; 82 return;
89 } 83 }
90 if (entity is File) { 84 if (entity is File) {
91 _serveFile(entity, request); 85 _serveFile(entity, request);
92 } else if (entity is Directory) { 86 } else if (entity is Directory) {
93 _serveDirectory(entity, request); 87 _serveDirectory(entity, request);
94 } else { 88 } else {
95 _serveErrorPage(HttpStatus.NOT_FOUND, request); 89 _serveErrorPage(HttpStatus.NOT_FOUND, request);
96 } 90 }
97 }); 91 });
98 } 92 }
99 93
100 void setDirectoryHandler(void callback(Directory dir, HttpRequest request)) { 94 void setDirectoryHandler(void callback(Directory dir, HttpRequest request)) {
101 _dirCallback = callback; 95 _dirCallback = callback;
102 } 96 }
103 97
104 void setErrorPageHandler(void callback(HttpRequest request)) { 98 void setErrorPageHandler(void callback(HttpRequest request)) {
105 _errorCallback = callback; 99 _errorCallback = callback;
106 } 100 }
107 101
108 Future<FileSystemEntity> _locateResource(Path path, 102 Future<FileSystemEntity> _locateResource(Path path,
109 Iterable<String> segments) { 103 Iterable<String> segments) {
104 path = path.canonicalize();
Lasse Reichstein Nielsen 2013/07/02 07:31:14 So you canonicalize after each segment is added. W
Anders Johnsen 2013/07/02 11:08:07 Yes, that's the idea.
105 if (path.segments().first == "..") return new Future.value(null);
110 Path fullPath() => new Path(root).join(path); 106 Path fullPath() => new Path(root).join(path);
111 return FileSystemEntity.type(fullPath().toNativePath(), followLinks: false) 107 return FileSystemEntity.type(fullPath().toNativePath(), followLinks: false)
112 .then((type) { 108 .then((type) {
113 switch (type) { 109 switch (type) {
114 case FileSystemEntityType.FILE: 110 case FileSystemEntityType.FILE:
115 if (segments.isEmpty) return new File.fromPath(fullPath()); 111 if (segments.isEmpty) return new File.fromPath(fullPath());
116 break; 112 break;
117 113
118 case FileSystemEntityType.DIRECTORY: 114 case FileSystemEntityType.DIRECTORY:
119 if (segments.isEmpty) { 115 if (segments.isEmpty) {
120 if (allowDirectoryListing) { 116 if (allowDirectoryListing) {
121 return new Directory.fromPath(fullPath()); 117 return new Directory.fromPath(fullPath());
122 } 118 }
123 } else { 119 } else {
124 return _locateResource(path.append(segments.first), 120 return _locateResource(path.append(segments.first),
125 segments.skip(1)); 121 segments.skip(1));
Lasse Reichstein Nielsen 2013/07/02 07:31:14 Ick. That's no way to treat an iterable. Consider
Anders Johnsen 2013/07/02 11:08:07 Done.
126 } 122 }
127 break; 123 break;
128 124
129 case FileSystemEntityType.LINK: 125 case FileSystemEntityType.LINK:
130 if (followLinks) { 126 if (followLinks) {
131 return new Link.fromPath(fullPath()).target() 127 return new Link.fromPath(fullPath()).target()
132 .then((target) { 128 .then((target) {
133 var targetPath = new Path(target).canonicalize(); 129 var targetPath = new Path(target).canonicalize();
134 if (targetPath.isAbsolute) return null; 130 if (targetPath.isAbsolute) return null;
135 targetPath = 131 targetPath = path.directoryPath.join(targetPath);
136 path.directoryPath.join(targetPath).canonicalize(); 132 return _locateResource(targetPath, segments);
137 if (targetPath.segments().isEmpty ||
138 targetPath.segments().first == '..') return null;
139 if (segments.isEmpty) {
140 return _locateResource(targetPath, []);
141 }
142 return _locateResource(targetPath.append(segments.first),
143 segments.skip(1));
144 }); 133 });
145 } 134 }
146 break; 135 break;
147 } 136 }
148 // Return `null` on fall-through, to indicate NOT_FOUND. 137 // Return `null` on fall-through, to indicate NOT_FOUND.
149 return null; 138 return null;
150 }); 139 });
151 } 140 }
152 141
153 void _serveFile(File file, HttpRequest request) { 142 void _serveFile(File file, HttpRequest request) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 361
373 Future close() => new Future.value(); 362 Future close() => new Future.value();
374 363
375 void setMimeType(var bytes) { 364 void setMimeType(var bytes) {
376 var mimeType = lookupMimeType(path, headerBytes: bytes); 365 var mimeType = lookupMimeType(path, headerBytes: bytes);
377 if (mimeType != null) { 366 if (mimeType != null) {
378 response.headers.contentType = ContentType.parse(mimeType); 367 response.headers.contentType = ContentType.parse(mimeType);
379 } 368 }
380 } 369 }
381 } 370 }
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