| 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:io'; | 6 import 'dart:io'; |
| 7 | 7 |
| 8 import "package:http_server/http_server.dart"; | 8 import "package:http_server/http_server.dart"; |
| 9 import 'package:path/path.dart' as pathos; | 9 import 'package:path/path.dart' as pathos; |
| 10 import "package:unittest/unittest.dart"; | 10 import "package:unittest/unittest.dart"; |
| 11 | 11 |
| 12 import 'utils.dart'; | 12 import 'utils.dart'; |
| 13 | 13 |
| 14 void _testVirDir(String name, dynamic func(HttpServer server, Directory dir)) { | |
| 15 test(name, () { | |
| 16 HttpServer server; | |
| 17 Directory dir; | |
| 18 | |
| 19 return HttpServer.bind('localhost', 0) | |
| 20 .then((value) { | |
| 21 server = value; | |
| 22 dir = Directory.systemTemp.createTempSync('http_server_virtual_'); | |
| 23 return func(server, dir); | |
| 24 }) | |
| 25 .whenComplete(() { | |
| 26 return Future.wait([server.close(), dir.delete(recursive: true)]); | |
| 27 }); | |
| 28 }); | |
| 29 } | |
| 30 | |
| 31 void _testEncoding(name, expected, [bool create = true]) { | 14 void _testEncoding(name, expected, [bool create = true]) { |
| 32 _testVirDir('encode-$name', (server, dir) { | 15 testVirtualDir('encode-$name', (dir) { |
| 33 if (create) new File('${dir.path}/$name').createSync(); | 16 if (create) new File('${dir.path}/$name').createSync(); |
| 34 var virDir = new VirtualDirectory(dir.path); | 17 var virDir = new VirtualDirectory(dir.path); |
| 35 virDir.allowDirectoryListing = true; | 18 virDir.allowDirectoryListing = true; |
| 36 | 19 |
| 37 virDir.serve(server); | 20 return getStatusCodeForVirtDir(virDir, '/$name') |
| 38 | |
| 39 return getStatusCode(server.port, '/$name') | |
| 40 .then((result) { | 21 .then((result) { |
| 41 expect(result, expected); | 22 expect(result, expected); |
| 42 }); | 23 }); |
| 43 }); | 24 }); |
| 44 } | 25 } |
| 45 | 26 |
| 46 void main() { | 27 void main() { |
| 47 group('serve-root', () { | 28 group('serve-root', () { |
| 48 _testVirDir('dir-exists', (server, dir) { | 29 testVirtualDir('dir-exists', (dir) { |
| 49 | 30 |
| 50 var virDir = new VirtualDirectory(dir.path); | 31 var virDir = new VirtualDirectory(dir.path); |
| 51 virDir.serve(server); | |
| 52 | 32 |
| 53 return getStatusCode(server.port, '/') | 33 return getStatusCodeForVirtDir(virDir, '/') |
| 54 .then((result) { | 34 .then((result) { |
| 55 expect(result, HttpStatus.NOT_FOUND); | 35 expect(result, HttpStatus.NOT_FOUND); |
| 56 }); | 36 }); |
| 57 }); | 37 }); |
| 58 | 38 |
| 59 _testVirDir('dir-not-exists', (server, dir) { | 39 testVirtualDir('dir-not-exists', (dir) { |
| 60 var virDir = new VirtualDirectory(pathos.join(dir.path + 'foo')); | 40 var virDir = new VirtualDirectory(pathos.join(dir.path + 'foo')); |
| 61 | 41 |
| 62 virDir.serve(server); | 42 return getStatusCodeForVirtDir(virDir, '/') |
| 63 | |
| 64 return getStatusCode(server.port, '/') | |
| 65 .then((result) { | 43 .then((result) { |
| 66 expect(result, HttpStatus.NOT_FOUND); | 44 expect(result, HttpStatus.NOT_FOUND); |
| 67 }); | 45 }); |
| 68 }); | 46 }); |
| 69 }); | 47 }); |
| 70 | 48 |
| 71 group('serve-file', () { | 49 group('serve-file', () { |
| 72 group('top-level', () { | 50 group('top-level', () { |
| 73 _testVirDir('file-exists', (server, dir) { | 51 testVirtualDir('file-exists', (dir) { |
| 74 var file = new File('${dir.path}/file')..createSync(); | 52 var file = new File('${dir.path}/file')..createSync(); |
| 75 var virDir = new VirtualDirectory(dir.path); | 53 var virDir = new VirtualDirectory(dir.path); |
| 76 | 54 return getStatusCodeForVirtDir(virDir, '/file') |
| 77 virDir.serve(server); | |
| 78 | |
| 79 return getStatusCode(server.port, '/file') | |
| 80 .then((result) { | 55 .then((result) { |
| 81 expect(result, HttpStatus.OK); | 56 expect(result, HttpStatus.OK); |
| 82 }); | 57 }); |
| 83 }); | 58 }); |
| 84 | 59 |
| 85 _testVirDir('file-not-exists', (server, dir) { | 60 testVirtualDir('file-not-exists', (dir) { |
| 86 var virDir = new VirtualDirectory(dir.path); | 61 var virDir = new VirtualDirectory(dir.path); |
| 87 | 62 |
| 88 virDir.serve(server); | 63 return getStatusCodeForVirtDir(virDir, '/file') |
| 89 | 64 .then((result) { |
| 90 return getStatusCode(server.port, '/file') | 65 expect(result, HttpStatus.NOT_FOUND); |
| 91 .then((result) { | 66 }); |
| 92 expect(result, HttpStatus.NOT_FOUND); | |
| 93 }); | |
| 94 }); | 67 }); |
| 95 }); | 68 }); |
| 96 | 69 |
| 97 group('in-dir', () { | 70 group('in-dir', () { |
| 98 _testVirDir('file-exists', (server, dir) { | 71 testVirtualDir('file-exists', (dir) { |
| 99 var dir2 = new Directory('${dir.path}/dir')..createSync(); | 72 var dir2 = new Directory('${dir.path}/dir')..createSync(); |
| 100 var file = new File('${dir2.path}/file')..createSync(); | 73 var file = new File('${dir2.path}/file')..createSync(); |
| 101 var virDir = new VirtualDirectory(dir.path); | 74 var virDir = new VirtualDirectory(dir.path); |
| 102 | 75 return getStatusCodeForVirtDir(virDir, '/dir/file') |
| 103 virDir.serve(server); | |
| 104 | |
| 105 return getStatusCode(server.port, '/dir/file') | |
| 106 .then((result) { | 76 .then((result) { |
| 107 expect(result, HttpStatus.OK); | 77 expect(result, HttpStatus.OK); |
| 108 }); | 78 }); |
| 109 }); | 79 }); |
| 110 | 80 |
| 111 _testVirDir('file-not-exists', (server, dir) { | 81 testVirtualDir('file-not-exists', (dir) { |
| 112 var dir2 = new Directory('${dir.path}/dir')..createSync(); | 82 var dir2 = new Directory('${dir.path}/dir')..createSync(); |
| 113 var file = new File('${dir.path}/file')..createSync(); | 83 var file = new File('${dir.path}/file')..createSync(); |
| 114 var virDir = new VirtualDirectory(dir.path); | 84 var virDir = new VirtualDirectory(dir.path); |
| 115 | 85 |
| 116 virDir.serve(server); | 86 return getStatusCodeForVirtDir(virDir, '/dir/file') |
| 117 | |
| 118 return getStatusCode(server.port, '/dir/file') | |
| 119 .then((result) { | 87 .then((result) { |
| 120 expect(result, HttpStatus.NOT_FOUND); | 88 expect(result, HttpStatus.NOT_FOUND); |
| 121 }); | 89 }); |
| 122 }); | 90 }); |
| 123 }); | 91 }); |
| 124 }); | 92 }); |
| 125 | 93 |
| 126 group('serve-dir', () { | 94 group('serve-dir', () { |
| 127 group('top-level', () { | 95 group('top-level', () { |
| 128 _testVirDir('simple', (server, dir) { | 96 testVirtualDir('simple', (dir) { |
| 129 var virDir = new VirtualDirectory(dir.path); | 97 var virDir = new VirtualDirectory(dir.path); |
| 130 virDir.allowDirectoryListing = true; | 98 virDir.allowDirectoryListing = true; |
| 131 | 99 |
| 132 virDir.serve(server); | 100 return getAsString(virDir, '/') |
| 133 | |
| 134 return getAsString(server.port, '/') | |
| 135 .then((result) { | 101 .then((result) { |
| 136 expect(result, contains('Index of /')); | 102 expect(result, contains('Index of /')); |
| 137 }); | 103 }); |
| 138 }); | 104 }); |
| 139 | 105 |
| 140 _testVirDir('files', (server, dir) { | 106 testVirtualDir('files', (dir) { |
| 141 var virDir = new VirtualDirectory(dir.path); | 107 var virDir = new VirtualDirectory(dir.path); |
| 142 for (int i = 0; i < 10; i++) { | 108 for (int i = 0; i < 10; i++) { |
| 143 new File('${dir.path}/$i').createSync(); | 109 new File('${dir.path}/$i').createSync(); |
| 144 } | 110 } |
| 145 virDir.allowDirectoryListing = true; | 111 virDir.allowDirectoryListing = true; |
| 146 | 112 |
| 147 virDir.serve(server); | 113 return getAsString(virDir, '/') |
| 148 | |
| 149 return getAsString(server.port, '/') | |
| 150 .then((result) { | 114 .then((result) { |
| 151 expect(result, contains('Index of /')); | 115 expect(result, contains('Index of /')); |
| 152 }); | 116 }); |
| 153 }); | 117 }); |
| 154 | 118 |
| 155 _testVirDir('dirs', (server, dir) { | 119 testVirtualDir('dirs', (dir) { |
| 156 var virDir = new VirtualDirectory(dir.path); | 120 var virDir = new VirtualDirectory(dir.path); |
| 157 for (int i = 0; i < 10; i++) { | 121 for (int i = 0; i < 10; i++) { |
| 158 new Directory('${dir.path}/$i').createSync(); | 122 new Directory('${dir.path}/$i').createSync(); |
| 159 } | 123 } |
| 160 virDir.allowDirectoryListing = true; | 124 virDir.allowDirectoryListing = true; |
| 161 | 125 |
| 162 virDir.serve(server); | 126 return getAsString(virDir, '/') |
| 163 | |
| 164 return getAsString(server.port, '/') | |
| 165 .then((result) { | 127 .then((result) { |
| 166 expect(result, contains('Index of /')); | 128 expect(result, contains('Index of /')); |
| 167 }); | 129 }); |
| 168 }); | 130 }); |
| 169 | 131 |
| 170 if (!Platform.isWindows) { | 132 if (!Platform.isWindows) { |
| 171 _testVirDir('recursive-link', (server, dir) { | 133 testVirtualDir('recursive-link', (dir) { |
| 172 var link = new Link('${dir.path}/recursive')..createSync('.'); | 134 var link = new Link('${dir.path}/recursive')..createSync('.'); |
| 173 var virDir = new VirtualDirectory(dir.path); | 135 var virDir = new VirtualDirectory(dir.path); |
| 174 virDir.allowDirectoryListing = true; | 136 virDir.allowDirectoryListing = true; |
| 175 | 137 |
| 176 virDir.serve(server); | |
| 177 | |
| 178 return Future.wait([ | 138 return Future.wait([ |
| 179 getAsString(server.port, '/').then( | 139 getAsString(virDir, '/').then( |
| 180 (s) => s.contains('recursive/')), | 140 (s) => s.contains('recursive/')), |
| 181 getAsString(server.port, '/').then( | 141 getAsString(virDir, '/').then( |
| 182 (s) => !s.contains('../')), | 142 (s) => !s.contains('../')), |
| 183 getAsString(server.port, '/').then( | 143 getAsString(virDir, '/').then( |
| 184 (s) => s.contains('Index of /')), | 144 (s) => s.contains('Index of /')), |
| 185 getAsString(server.port, '/recursive').then( | 145 getAsString(virDir, '/recursive').then( |
| 186 (s) => s.contains('recursive/')), | 146 (s) => s.contains('recursive/')), |
| 187 getAsString(server.port, '/recursive').then( | 147 getAsString(virDir, '/recursive').then( |
| 188 (s) => s.contains('../')), | 148 (s) => s.contains('../')), |
| 189 getAsString(server.port, '/recursive').then( | 149 getAsString(virDir, '/recursive').then( |
| 190 (s) => s.contains('Index of /recursive'))]) | 150 (s) => s.contains('Index of /recursive'))]) |
| 191 .then((result) { | 151 .then((result) { |
| 192 expect(result, equals([true, true, true, true, true, true])); | 152 expect(result, equals([true, true, true, true, true, true])); |
| 193 }); | 153 }); |
| 194 }); | 154 }); |
| 195 } | 155 } |
| 196 }); | 156 }); |
| 197 | 157 |
| 198 group('custom', () { | 158 group('custom', () { |
| 199 _testVirDir('simple', (server, dir) { | 159 testVirtualDir('simple', (dir) { |
| 200 var virDir = new VirtualDirectory(dir.path); | 160 var virDir = new VirtualDirectory(dir.path); |
| 201 virDir.allowDirectoryListing = true; | 161 virDir.allowDirectoryListing = true; |
| 202 virDir.directoryHandler = (dir2, request) { | 162 virDir.directoryHandler = (dir2, request) { |
| 203 expect(dir2, isNotNull); | 163 expect(dir2, isNotNull); |
| 204 expect(FileSystemEntity.identicalSync(dir.path, dir2.path), isTrue); | 164 expect(FileSystemEntity.identicalSync(dir.path, dir2.path), isTrue); |
| 205 request.response.write('My handler ${request.uri.path}'); | 165 request.response.write('My handler ${request.uri.path}'); |
| 206 request.response.close(); | 166 request.response.close(); |
| 207 }; | 167 }; |
| 208 | 168 |
| 209 virDir.serve(server); | 169 return getAsString(virDir, '/') |
| 210 | |
| 211 return getAsString(server.port, '/') | |
| 212 .then((result) { | 170 .then((result) { |
| 213 expect(result, 'My handler /'); | 171 expect(result, 'My handler /'); |
| 214 }); | 172 }); |
| 215 }); | 173 }); |
| 216 | 174 |
| 217 _testVirDir('index-1', (server, dir) { | 175 testVirtualDir('index-1', (dir) { |
| 218 new File('${dir.path}/index.html').writeAsStringSync('index file'); | 176 new File('${dir.path}/index.html').writeAsStringSync('index file'); |
| 219 var virDir = new VirtualDirectory(dir.path); | 177 var virDir = new VirtualDirectory(dir.path); |
| 220 virDir.allowDirectoryListing = true; | 178 virDir.allowDirectoryListing = true; |
| 221 virDir.directoryHandler = (dir2, request) { | 179 virDir.directoryHandler = (dir2, request) { |
| 222 // Redirect directory-requests to index.html files. | 180 // Redirect directory-requests to index.html files. |
| 223 var indexUri = new Uri.file(dir2.path).resolve('index.html'); | 181 var indexUri = new Uri.file(dir2.path).resolve('index.html'); |
| 224 virDir.serveFile(new File(indexUri.toFilePath()), request); | 182 return virDir.serveFile(new File(indexUri.toFilePath()), request); |
| 225 }; | 183 }; |
| 226 virDir.serve(server); | 184 |
| 227 return getAsString(server.port, '/') | 185 return getAsString(virDir, '/') |
| 228 .then((result) { | 186 .then((result) { |
| 229 expect(result, 'index file'); | 187 expect(result, 'index file'); |
| 230 }); | 188 }); |
| 231 }); | 189 }); |
| 232 | 190 |
| 233 _testVirDir('index-2', (server, dir) { | 191 testVirtualDir('index-2', (dir) { |
| 234 new File('${dir.path}/dir/index.html') | 192 new File('${dir.path}/dir/index.html') |
| 235 ..createSync(recursive: true) | 193 ..createSync(recursive: true) |
| 236 ..writeAsStringSync('index file'); | 194 ..writeAsStringSync('index file'); |
| 237 var virDir = new VirtualDirectory(dir.path); | 195 var virDir = new VirtualDirectory(dir.path); |
| 238 virDir.allowDirectoryListing = true; | 196 virDir.allowDirectoryListing = true; |
| 239 virDir.directoryHandler = (dir2, request) { | 197 virDir.directoryHandler = (dir2, request) { |
| 240 // Redirect directory-requests to index.html files. | 198 // Redirect directory-requests to index.html files. |
| 241 var indexUri = new Uri.file(dir2.path).resolve('index.html'); | 199 var indexUri = new Uri.file(dir2.path).resolve('index.html'); |
| 242 virDir.serveFile(new File(indexUri.toFilePath()), request); | 200 return virDir.serveFile(new File(indexUri.toFilePath()), request); |
| 243 }; | 201 }; |
| 244 virDir.serve(server); | 202 |
| 245 return getAsString(server.port, '/dir') | 203 return getAsString(virDir, '/dir') |
| 246 .then((result) { | 204 .then((result) { |
| 247 expect(result, 'index file'); | 205 expect(result, 'index file'); |
| 248 }); | 206 }); |
| 249 }); | 207 }); |
| 250 }); | 208 }); |
| 251 }); | 209 }); |
| 252 | 210 |
| 253 group('links', () { | 211 group('links', () { |
| 254 if (!Platform.isWindows) { | 212 if (!Platform.isWindows) { |
| 255 group('follow-links', () { | 213 group('follow-links', () { |
| 256 _testVirDir('dir-link', (server, dir) { | 214 testVirtualDir('dir-link', (dir) { |
| 257 var dir2 = new Directory('${dir.path}/dir2')..createSync(); | 215 var dir2 = new Directory('${dir.path}/dir2')..createSync(); |
| 258 var link = new Link('${dir.path}/dir3')..createSync('dir2'); | 216 var link = new Link('${dir.path}/dir3')..createSync('dir2'); |
| 259 var file = new File('${dir2.path}/file')..createSync(); | 217 var file = new File('${dir2.path}/file')..createSync(); |
| 260 var virDir = new VirtualDirectory(dir.path); | 218 var virDir = new VirtualDirectory(dir.path); |
| 261 virDir.followLinks = true; | 219 virDir.followLinks = true; |
| 262 | 220 |
| 263 virDir.serve(server); | 221 return getStatusCodeForVirtDir(virDir, '/dir3/file') |
| 264 | |
| 265 return getStatusCode(server.port, '/dir3/file') | |
| 266 .then((result) { | 222 .then((result) { |
| 267 expect(result, HttpStatus.OK); | 223 expect(result, HttpStatus.OK); |
| 268 }); | 224 }); |
| 269 }); | 225 }); |
| 270 | 226 |
| 271 _testVirDir('root-link', (server, dir) { | 227 testVirtualDir('root-link', (dir) { |
| 272 var link = new Link('${dir.path}/dir3')..createSync('.'); | 228 var link = new Link('${dir.path}/dir3')..createSync('.'); |
| 273 var file = new File('${dir.path}/file')..createSync(); | 229 var file = new File('${dir.path}/file')..createSync(); |
| 274 var virDir = new VirtualDirectory(dir.path); | 230 var virDir = new VirtualDirectory(dir.path); |
| 275 virDir.followLinks = true; | 231 virDir.followLinks = true; |
| 276 | 232 |
| 277 virDir.serve(server); | 233 return getStatusCodeForVirtDir(virDir, '/dir3/file') |
| 278 | |
| 279 return getStatusCode(server.port, '/dir3/file') | |
| 280 .then((result) { | 234 .then((result) { |
| 281 expect(result, HttpStatus.OK); | 235 expect(result, HttpStatus.OK); |
| 282 }); | 236 }); |
| 283 }); | 237 }); |
| 284 | 238 |
| 285 group('bad-links', () { | 239 group('bad-links', () { |
| 286 _testVirDir('absolute-link', (server, dir) { | 240 testVirtualDir('absolute-link', (dir) { |
| 287 var file = new File('${dir.path}/file')..createSync(); | 241 var file = new File('${dir.path}/file')..createSync(); |
| 288 var link = new Link('${dir.path}/file2') | 242 var link = new Link('${dir.path}/file2') |
| 289 ..createSync('${dir.path}/file'); | 243 ..createSync('${dir.path}/file'); |
| 290 var virDir = new VirtualDirectory(dir.path); | 244 var virDir = new VirtualDirectory(dir.path); |
| 291 virDir.followLinks = true; | 245 virDir.followLinks = true; |
| 292 | 246 |
| 293 virDir.serve(server); | 247 return getStatusCodeForVirtDir(virDir, '/file2') |
| 294 | |
| 295 return new HttpClient().get('localhost', | |
| 296 server.port, | |
| 297 '/file2') | |
| 298 .then((request) => request.close()) | |
| 299 .then((response) => response.drain().then( | |
| 300 (_) => response.statusCode)) | |
| 301 .then((result) { | 248 .then((result) { |
| 302 expect(result, HttpStatus.NOT_FOUND); | 249 expect(result, HttpStatus.NOT_FOUND); |
| 303 }); | 250 }); |
| 304 }); | 251 }); |
| 305 | 252 |
| 306 _testVirDir('relative-parent-link', (server, dir) { | 253 testVirtualDir('relative-parent-link', (dir) { |
| 307 var dir2 = new Directory('${dir.path}/dir')..createSync(); | 254 var dir2 = new Directory('${dir.path}/dir')..createSync(); |
| 308 var file = new File('${dir.path}/file')..createSync(); | 255 var file = new File('${dir.path}/file')..createSync(); |
| 309 var link = new Link('${dir2.path}/file') | 256 var link = new Link('${dir2.path}/file') |
| 310 ..createSync('../file'); | 257 ..createSync('../file'); |
| 311 var virDir = new VirtualDirectory(dir2.path); | 258 var virDir = new VirtualDirectory(dir2.path); |
| 312 virDir.followLinks = true; | 259 virDir.followLinks = true; |
| 313 | 260 |
| 314 virDir.serve(server); | 261 return getStatusCodeForVirtDir(virDir, '/dir3/file') |
| 315 | |
| 316 return new HttpClient().get('localhost', | |
| 317 server.port, | |
| 318 '/dir3/file') | |
| 319 .then((request) => request.close()) | |
| 320 .then((response) => response.drain().then( | |
| 321 (_) => response.statusCode)) | |
| 322 .then((result) { | 262 .then((result) { |
| 323 expect(result, HttpStatus.NOT_FOUND); | 263 expect(result, HttpStatus.NOT_FOUND); |
| 324 }); | 264 }); |
| 325 }); | 265 }); |
| 326 }); | 266 }); |
| 327 }); | 267 }); |
| 328 | 268 |
| 329 group('not-follow-links', () { | 269 group('not-follow-links', () { |
| 330 _testVirDir('dir-link', (server, dir) { | 270 testVirtualDir('dir-link', (dir) { |
| 331 var dir2 = new Directory('${dir.path}/dir2')..createSync(); | 271 var dir2 = new Directory('${dir.path}/dir2')..createSync(); |
| 332 var link = new Link('${dir.path}/dir3')..createSync('dir2'); | 272 var link = new Link('${dir.path}/dir3')..createSync('dir2'); |
| 333 var file = new File('${dir2.path}/file')..createSync(); | 273 var file = new File('${dir2.path}/file')..createSync(); |
| 334 var virDir = new VirtualDirectory(dir.path); | 274 var virDir = new VirtualDirectory(dir.path); |
| 335 virDir.followLinks = false; | 275 virDir.followLinks = false; |
| 336 | 276 |
| 337 virDir.serve(server); | 277 return getStatusCodeForVirtDir(virDir, '/dir3/file') |
| 338 | |
| 339 return getStatusCode(server.port, '/dir3/file') | |
| 340 .then((result) { | 278 .then((result) { |
| 341 expect(result, HttpStatus.NOT_FOUND); | 279 expect(result, HttpStatus.NOT_FOUND); |
| 342 }); | 280 }); |
| 343 }); | 281 }); |
| 344 }); | 282 }); |
| 345 | 283 |
| 346 group('follow-links', () { | 284 group('follow-links', () { |
| 347 group('no-root-jail', () { | 285 group('no-root-jail', () { |
| 348 _testVirDir('absolute-link', (server, dir) { | 286 testVirtualDir('absolute-link', (dir) { |
| 349 var file = new File('${dir.path}/file')..createSync(); | 287 var file = new File('${dir.path}/file')..createSync(); |
| 350 var link = new Link('${dir.path}/file2') | 288 var link = new Link('${dir.path}/file2') |
| 351 ..createSync('${dir.path}/file'); | 289 ..createSync('${dir.path}/file'); |
| 352 var virDir = new VirtualDirectory(dir.path); | 290 var virDir = new VirtualDirectory(dir.path); |
| 353 virDir.followLinks = true; | 291 virDir.followLinks = true; |
| 354 virDir.jailRoot = false; | 292 virDir.jailRoot = false; |
| 355 | 293 |
| 356 virDir.serve(server); | 294 return getStatusCodeForVirtDir(virDir, '/file2') |
| 357 | |
| 358 return new HttpClient().get('localhost', | |
| 359 server.port, | |
| 360 '/file2') | |
| 361 .then((request) => request.close()) | |
| 362 .then((response) => response.drain().then( | |
| 363 (_) => response.statusCode)) | |
| 364 .then((result) { | 295 .then((result) { |
| 365 expect(result, HttpStatus.OK); | 296 expect(result, HttpStatus.OK); |
| 366 }); | 297 }); |
| 367 }); | 298 }); |
| 368 | 299 |
| 369 _testVirDir('relative-parent-link', (server, dir) { | 300 testVirtualDir('relative-parent-link', (dir) { |
| 370 var dir2 = new Directory('${dir.path}/dir')..createSync(); | 301 var dir2 = new Directory('${dir.path}/dir')..createSync(); |
| 371 var file = new File('${dir.path}/file')..createSync(); | 302 var file = new File('${dir.path}/file')..createSync(); |
| 372 var link = new Link('${dir2.path}/file') | 303 var link = new Link('${dir2.path}/file') |
| 373 ..createSync('../file'); | 304 ..createSync('../file'); |
| 374 var virDir = new VirtualDirectory(dir2.path); | 305 var virDir = new VirtualDirectory(dir2.path); |
| 375 virDir.followLinks = true; | 306 virDir.followLinks = true; |
| 376 virDir.jailRoot = false; | 307 virDir.jailRoot = false; |
| 377 | 308 |
| 378 virDir.serve(server); | 309 return getStatusCodeForVirtDir(virDir, '/file') |
| 379 | |
| 380 return new HttpClient().get('localhost', | |
| 381 server.port, | |
| 382 '/file') | |
| 383 .then((request) => request.close()) | |
| 384 .then((response) => response.drain().then( | |
| 385 (_) => response.statusCode)) | |
| 386 .then((result) { | 310 .then((result) { |
| 387 expect(result, HttpStatus.OK); | 311 expect(result, HttpStatus.OK); |
| 388 }); | 312 }); |
| 389 }); | 313 }); |
| 390 }); | 314 }); |
| 391 }); | 315 }); |
| 392 } | 316 } |
| 393 }); | 317 }); |
| 394 | 318 |
| 395 group('last-modified', () { | 319 group('last-modified', () { |
| 396 group('file', () { | 320 group('file', () { |
| 397 _testVirDir('file-exists', (server, dir) { | 321 testVirtualDir('file-exists', (dir) { |
| 398 var file = new File('${dir.path}/file')..createSync(); | 322 var file = new File('${dir.path}/file')..createSync(); |
| 399 var virDir = new VirtualDirectory(dir.path); | 323 var virDir = new VirtualDirectory(dir.path); |
| 400 | 324 |
| 401 virDir.serve(server); | 325 return getHeaders(virDir, '/file') |
| 402 | |
| 403 return getHeaders(server.port, '/file') | |
| 404 .then((headers) { | 326 .then((headers) { |
| 405 expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull); | 327 expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull); |
| 406 return HttpDate.parse( | 328 var lastModified = HttpDate.parse( |
| 407 headers.value(HttpHeaders.LAST_MODIFIED)); | 329 headers.value(HttpHeaders.LAST_MODIFIED)); |
| 408 }) | 330 |
| 409 .then((lastModified) { | 331 return getStatusCodeForVirtDir( |
| 410 return getStatusCode( | 332 virDir, '/file', ifModifiedSince: lastModified); |
| 411 server.port, '/file', ifModifiedSince: lastModified); | |
| 412 }) | 333 }) |
| 413 .then((result) { | 334 .then((result) { |
| 414 expect(result, HttpStatus.NOT_MODIFIED); | 335 expect(result, HttpStatus.NOT_MODIFIED); |
| 415 }); | 336 }); |
| 416 }); | 337 }); |
| 417 | 338 |
| 418 _testVirDir('file-changes', (server, dir) { | 339 testVirtualDir('file-changes', (dir) { |
| 419 var file = new File('${dir.path}/file')..createSync(); | 340 var file = new File('${dir.path}/file')..createSync(); |
| 420 var virDir = new VirtualDirectory(dir.path); | 341 var virDir = new VirtualDirectory(dir.path); |
| 421 | 342 |
| 422 virDir.serve(server); | 343 return getHeaders(virDir, '/file') |
| 423 | |
| 424 return getHeaders(server.port, '/file') | |
| 425 .then((headers) { | 344 .then((headers) { |
| 426 expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull); | 345 expect(headers.value(HttpHeaders.LAST_MODIFIED), isNotNull); |
| 427 return HttpDate.parse( | 346 var lastModified = HttpDate.parse( |
| 428 headers.value(HttpHeaders.LAST_MODIFIED)); | 347 headers.value(HttpHeaders.LAST_MODIFIED)); |
| 429 }) | 348 |
| 430 .then((lastModified) { | |
| 431 // Fake file changed by moving date back in time. | 349 // Fake file changed by moving date back in time. |
| 432 lastModified = lastModified.subtract( | 350 lastModified = lastModified.subtract( |
| 433 const Duration(seconds: 10)); | 351 const Duration(seconds: 10)); |
| 434 return getStatusCode( | 352 |
| 435 server.port, '/file', ifModifiedSince: lastModified); | 353 return getStatusCodeForVirtDir(virDir, '/file', |
| 354 ifModifiedSince: lastModified); |
| 436 }) | 355 }) |
| 437 .then((result) { | 356 .then((result) { |
| 438 expect(result, HttpStatus.OK); | 357 expect(result, HttpStatus.OK); |
| 439 }); | 358 }); |
| 440 }); | 359 }); |
| 441 }); | 360 }); |
| 442 }); | 361 }); |
| 443 | 362 |
| 444 group('content-type', () { | 363 group('content-type', () { |
| 445 group('mime-type', () { | 364 group('mime-type', () { |
| 446 _testVirDir('from-path', (server, dir) { | 365 testVirtualDir('from-path', (dir) { |
| 447 var file = new File('${dir.path}/file.jpg')..createSync(); | 366 var file = new File('${dir.path}/file.jpg')..createSync(); |
| 448 var virDir = new VirtualDirectory(dir.path); | 367 var virDir = new VirtualDirectory(dir.path); |
| 449 | 368 |
| 450 virDir.serve(server); | 369 return getHeaders(virDir, '/file.jpg') |
| 451 | 370 .then((headers) { |
| 452 return getHeaders(server.port, '/file.jpg') | 371 var contentType = headers.contentType.toString(); |
| 453 .then((headers) => headers.contentType.toString()) | 372 expect(contentType, 'image/jpeg'); |
| 454 .then((result) { | |
| 455 expect(result, 'image/jpeg'); | |
| 456 }); | 373 }); |
| 457 }); | 374 }); |
| 458 | 375 |
| 459 _testVirDir('from-magic-number', (server, dir) { | 376 testVirtualDir('from-magic-number', (dir) { |
| 460 var file = new File('${dir.path}/file.jpg')..createSync(); | 377 var file = new File('${dir.path}/file.jpg')..createSync(); |
| 461 file.writeAsBytesSync( | 378 file.writeAsBytesSync( |
| 462 [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); | 379 [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); |
| 463 var virDir = new VirtualDirectory(dir.path); | 380 var virDir = new VirtualDirectory(dir.path); |
| 464 | 381 |
| 465 virDir.serve(server); | 382 return getHeaders(virDir, '/file.jpg') |
| 466 | 383 .then((headers) { |
| 467 return getHeaders(server.port, '/file.jpg') | 384 var contentType = headers.contentType.toString(); |
| 468 .then((headers) => headers.contentType.toString()) | 385 expect(contentType, 'image/png'); |
| 469 .then((result) { | |
| 470 expect(result, 'image/png'); | |
| 471 }); | 386 }); |
| 472 }); | 387 }); |
| 473 }); | 388 }); |
| 474 }); | 389 }); |
| 475 | 390 |
| 476 group('error-page', () { | 391 group('error-page', () { |
| 477 _testVirDir('default', (server, dir) { | 392 testVirtualDir('default', (dir) { |
| 478 var virDir = new VirtualDirectory(pathos.join(dir.path, 'foo')); | 393 var virDir = new VirtualDirectory(pathos.join(dir.path, 'foo')); |
| 479 | 394 |
| 480 virDir.serve(server); | 395 return getAsString(virDir, '/') |
| 481 | |
| 482 return getAsString(server.port, '/') | |
| 483 .then((result) { | 396 .then((result) { |
| 484 expect(result, matches(new RegExp('404.*Not Found'))); | 397 expect(result, matches(new RegExp('404.*Not Found'))); |
| 485 }); | 398 }); |
| 486 }); | 399 }); |
| 487 | 400 |
| 488 _testVirDir('custom', (server, dir) { | 401 testVirtualDir('custom', (dir) { |
| 489 var virDir = new VirtualDirectory(pathos.join(dir.path, 'foo')); | 402 var virDir = new VirtualDirectory(pathos.join(dir.path, 'foo')); |
| 490 | 403 |
| 491 virDir.errorPageHandler = (request) { | 404 virDir.errorPageHandler = (request) { |
| 492 request.response.write('my-page '); | 405 request.response.write('my-page '); |
| 493 request.response.write(request.response.statusCode); | 406 request.response.write(request.response.statusCode); |
| 494 request.response.close(); | 407 request.response.close(); |
| 495 }; | 408 }; |
| 496 virDir.serve(server); | |
| 497 | 409 |
| 498 return getAsString(server.port, '/') | 410 return getAsString(virDir, '/') |
| 499 .then((result) { | 411 .then((result) { |
| 500 expect(result, 'my-page 404'); | 412 expect(result, 'my-page 404'); |
| 501 }); | 413 }); |
| 502 }); | 414 }); |
| 503 }); | 415 }); |
| 504 | 416 |
| 505 group('escape-root', () { | 417 group('escape-root', () { |
| 506 _testVirDir('escape1', (server, dir) { | 418 testVirtualDir('escape1', (dir) { |
| 507 var virDir = new VirtualDirectory(dir.path); | 419 var virDir = new VirtualDirectory(dir.path); |
| 508 virDir.allowDirectoryListing = true; | 420 virDir.allowDirectoryListing = true; |
| 509 | 421 |
| 510 virDir.serve(server); | 422 return getStatusCodeForVirtDir(virDir, '/../') |
| 511 | |
| 512 return getStatusCode(server.port, '/../') | |
| 513 .then((result) { | 423 .then((result) { |
| 514 expect(result, HttpStatus.NOT_FOUND); | 424 expect(result, HttpStatus.NOT_FOUND); |
| 515 }); | 425 }); |
| 516 }); | 426 }); |
| 517 | 427 |
| 518 _testVirDir('escape2', (server, dir) { | 428 testVirtualDir('escape2', (dir) { |
| 519 new Directory('${dir.path}/dir').createSync(); | 429 new Directory('${dir.path}/dir').createSync(); |
| 520 var virDir = new VirtualDirectory(dir.path); | 430 var virDir = new VirtualDirectory(dir.path); |
| 521 virDir.allowDirectoryListing = true; | 431 virDir.allowDirectoryListing = true; |
| 522 | 432 |
| 523 virDir.serve(server); | 433 return getStatusCodeForVirtDir(virDir, '/dir/../../') |
| 524 | |
| 525 return getStatusCode(server.port, '/dir/../../') | |
| 526 .then((result) { | 434 .then((result) { |
| 527 expect(result, HttpStatus.NOT_FOUND); | 435 expect(result, HttpStatus.NOT_FOUND); |
| 528 }); | 436 }); |
| 529 }); | 437 }); |
| 530 }); | 438 }); |
| 531 | 439 |
| 532 group('url-decode', () { | 440 group('url-decode', () { |
| 533 _testVirDir('with-space', (server, dir) { | 441 testVirtualDir('with-space', (dir) { |
| 534 var file = new File('${dir.path}/my file')..createSync(); | 442 var file = new File('${dir.path}/my file')..createSync(); |
| 535 var virDir = new VirtualDirectory(dir.path); | 443 var virDir = new VirtualDirectory(dir.path); |
| 536 | 444 |
| 537 virDir.serve(server); | 445 return getStatusCodeForVirtDir(virDir, '/my file') |
| 538 | |
| 539 return getStatusCode(server.port, '/my file') | |
| 540 .then((result) { | 446 .then((result) { |
| 541 expect(result, HttpStatus.OK); | 447 expect(result, HttpStatus.OK); |
| 542 }); | 448 }); |
| 543 }); | 449 }); |
| 544 | 450 |
| 545 _testVirDir('encoded-space', (server, dir) { | 451 testVirtualDir('encoded-space', (dir) { |
| 546 var file = new File('${dir.path}/my file')..createSync(); | 452 var file = new File('${dir.path}/my file')..createSync(); |
| 547 var virDir = new VirtualDirectory(dir.path); | 453 var virDir = new VirtualDirectory(dir.path); |
| 548 | 454 |
| 549 virDir.serve(server); | 455 return getStatusCodeForVirtDir(virDir, '/my%20file') |
| 550 | |
| 551 return getStatusCode(server.port, '/my%20file') | |
| 552 .then((result) { | 456 .then((result) { |
| 553 expect(result, HttpStatus.NOT_FOUND); | 457 expect(result, HttpStatus.NOT_FOUND); |
| 554 }); | 458 }); |
| 555 }); | 459 }); |
| 556 | 460 |
| 557 _testVirDir('encoded-path-separator', (server, dir) { | 461 testVirtualDir('encoded-path-separator', (dir) { |
| 558 new Directory('${dir.path}/a').createSync(); | 462 new Directory('${dir.path}/a').createSync(); |
| 559 new Directory('${dir.path}/a/b').createSync(); | 463 new Directory('${dir.path}/a/b').createSync(); |
| 560 new Directory('${dir.path}/a/b/c').createSync(); | 464 new Directory('${dir.path}/a/b/c').createSync(); |
| 561 var virDir = new VirtualDirectory(dir.path); | 465 var virDir = new VirtualDirectory(dir.path); |
| 562 virDir.allowDirectoryListing = true; | 466 virDir.allowDirectoryListing = true; |
| 563 | 467 |
| 564 virDir.serve(server); | 468 return getStatusCodeForVirtDir(virDir, '/a%2fb/c', rawPath: true) |
| 565 | |
| 566 return getStatusCode(server.port, '/a%2fb/c', rawPath: true) | |
| 567 .then((result) { | 469 .then((result) { |
| 568 expect(result, HttpStatus.NOT_FOUND); | 470 expect(result, HttpStatus.NOT_FOUND); |
| 569 }); | 471 }); |
| 570 }); | 472 }); |
| 571 | 473 |
| 572 _testVirDir('encoded-null', (server, dir) { | 474 testVirtualDir('encoded-null', (dir) { |
| 573 var virDir = new VirtualDirectory(dir.path); | 475 var virDir = new VirtualDirectory(dir.path); |
| 574 virDir.allowDirectoryListing = true; | 476 virDir.allowDirectoryListing = true; |
| 575 | 477 |
| 576 virDir.serve(server); | 478 return getStatusCodeForVirtDir(virDir, '/%00', rawPath: true) |
| 577 | |
| 578 return getStatusCode(server.port, '/%00', rawPath: true) | |
| 579 .then((result) { | 479 .then((result) { |
| 580 expect(result, HttpStatus.NOT_FOUND); | 480 expect(result, HttpStatus.NOT_FOUND); |
| 581 }); | 481 }); |
| 582 }); | 482 }); |
| 583 | 483 |
| 584 _testEncoding('..', HttpStatus.NOT_FOUND, false); | 484 _testEncoding('..', HttpStatus.NOT_FOUND, false); |
| 585 _testEncoding('%2e%2e', HttpStatus.OK); | 485 _testEncoding('%2e%2e', HttpStatus.OK); |
| 586 _testEncoding('%252e%252e', HttpStatus.OK); | 486 _testEncoding('%252e%252e', HttpStatus.OK); |
| 587 _testEncoding('/', HttpStatus.OK, false); | 487 _testEncoding('/', HttpStatus.OK, false); |
| 588 _testEncoding('%2f', HttpStatus.NOT_FOUND, false); | 488 _testEncoding('%2f', HttpStatus.NOT_FOUND, false); |
| 589 _testEncoding('%2f', HttpStatus.OK, true); | 489 _testEncoding('%2f', HttpStatus.OK, true); |
| 590 }); | 490 }); |
| 591 | 491 |
| 592 group('serve-file', () { | 492 group('serve-file', () { |
| 593 _testVirDir('from-dir-handler', (server, dir) { | 493 testVirtualDir('from-dir-handler', (dir) { |
| 594 new File('${dir.path}/file')..writeAsStringSync('file contents'); | 494 new File('${dir.path}/file')..writeAsStringSync('file contents'); |
| 595 var virDir = new VirtualDirectory(dir.path); | 495 var virDir = new VirtualDirectory(dir.path); |
| 596 virDir.allowDirectoryListing = true; | 496 virDir.allowDirectoryListing = true; |
| 597 virDir.directoryHandler = (d, request) { | 497 virDir.directoryHandler = (d, request) { |
| 598 expect(FileSystemEntity.identicalSync(dir.path, d.path), isTrue); | 498 expect(FileSystemEntity.identicalSync(dir.path, d.path), isTrue); |
| 599 virDir.serveFile(new File('${d.path}/file'), request); | 499 return virDir.serveFile(new File('${d.path}/file'), request); |
| 600 }; | 500 }; |
| 601 | 501 |
| 602 virDir.serve(server); | 502 return getAsString(virDir, '/') |
| 603 | |
| 604 return getAsString(server.port, '/') | |
| 605 .then((result) { | 503 .then((result) { |
| 606 expect(result, 'file contents'); | 504 expect(result, 'file contents'); |
| 607 }); | 505 }); |
| 608 }); | 506 }); |
| 609 }); | 507 }); |
| 610 } | 508 } |
| OLD | NEW |