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 library http_server; | 5 library http_server; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
10 import 'dart:convert' show HtmlEscape; | 10 import 'dart:convert' show HtmlEscape; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 /// as the default. This will serve file lib/BAR from the package PAZ. | 55 /// as the default. This will serve file lib/BAR from the package PAZ. |
56 /// /ws: This will upgrade the connection to a WebSocket connection and echo | 56 /// /ws: This will upgrade the connection to a WebSocket connection and echo |
57 /// all data back to the client. | 57 /// all data back to the client. |
58 /// | 58 /// |
59 /// In case a path does not refer to a file but rather to a directory, a | 59 /// In case a path does not refer to a file but rather to a directory, a |
60 /// directory listing will be displayed. | 60 /// directory listing will be displayed. |
61 | 61 |
62 const PREFIX_BUILDDIR = 'root_build'; | 62 const PREFIX_BUILDDIR = 'root_build'; |
63 const PREFIX_DARTDIR = 'root_dart'; | 63 const PREFIX_DARTDIR = 'root_dart'; |
64 | 64 |
65 main(List<String> arguments) { | 65 void main(List<String> arguments) { |
66 // This script is in [dart]/tools/testing/dart. | 66 // This script is in [dart]/tools/testing/dart. |
67 TestUtils.setDartDirUri(Platform.script.resolve('../../..')); | 67 TestUtils.setDartDirUri(Platform.script.resolve('../../..')); |
68 /** Convenience method for local testing. */ | 68 /** Convenience method for local testing. */ |
69 var parser = new ArgParser(); | 69 var parser = new ArgParser(); |
70 parser.addOption('port', | 70 parser.addOption('port', |
71 abbr: 'p', | 71 abbr: 'p', |
72 help: 'The main server port we wish to respond to requests.', | 72 help: 'The main server port we wish to respond to requests.', |
73 defaultsTo: '0'); | 73 defaultsTo: '0'); |
74 parser.addOption('crossOriginPort', | 74 parser.addOption('crossOriginPort', |
75 abbr: 'c', | 75 abbr: 'c', |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 static final _HARMLESS_REQUEST_PATH_ENDINGS = [ | 114 static final _HARMLESS_REQUEST_PATH_ENDINGS = [ |
115 "/apple-touch-icon.png", | 115 "/apple-touch-icon.png", |
116 "/apple-touch-icon-precomposed.png", | 116 "/apple-touch-icon-precomposed.png", |
117 "/favicon.ico", | 117 "/favicon.ico", |
118 "/foo", | 118 "/foo", |
119 "/bar", | 119 "/bar", |
120 "/NonExistingFile", | 120 "/NonExistingFile", |
121 "IntentionallyMissingFile", | 121 "IntentionallyMissingFile", |
122 ]; | 122 ]; |
123 | 123 |
124 List _serverList = []; | 124 final List<HttpServer> _serverList = []; |
125 Uri _buildDirectory = null; | 125 Uri _buildDirectory; |
126 Uri _dartDirectory = null; | 126 Uri _dartDirectory; |
127 Uri _packageRoot; | 127 Uri _packageRoot; |
128 Uri _packages; | 128 Uri _packages; |
129 final bool useContentSecurityPolicy; | 129 final bool useContentSecurityPolicy; |
130 final String runtime; | 130 final String runtime; |
131 DispatchingServer _server; | 131 DispatchingServer _server; |
132 SyncPackageResolver _resolver; | 132 SyncPackageResolver _resolver; |
133 | 133 |
134 TestingServers(String buildDirectory, this.useContentSecurityPolicy, | 134 TestingServers(String buildDirectory, this.useContentSecurityPolicy, |
135 [String this.runtime = 'none', | 135 [String this.runtime = 'none', |
136 String dartDirectory, | 136 String dartDirectory, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 | 210 |
211 void _onError(e) { | 211 void _onError(e) { |
212 DebugLogger.error('HttpServer: an error occured', e); | 212 DebugLogger.error('HttpServer: an error occured', e); |
213 } | 213 } |
214 | 214 |
215 Future _startHttpServer(String host, {int port: 0, int allowedPort: -1}) { | 215 Future _startHttpServer(String host, {int port: 0, int allowedPort: -1}) { |
216 return HttpServer.bind(host, port).then((HttpServer httpServer) { | 216 return HttpServer.bind(host, port).then((HttpServer httpServer) { |
217 var server = new DispatchingServer(httpServer, _onError, _sendNotFound); | 217 var server = new DispatchingServer(httpServer, _onError, _sendNotFound); |
218 server.addHandler('/echo', _handleEchoRequest); | 218 server.addHandler('/echo', _handleEchoRequest); |
219 server.addHandler('/ws', _handleWebSocketRequest); | 219 server.addHandler('/ws', _handleWebSocketRequest); |
220 fileHandler(request) { | 220 fileHandler(HttpRequest request) { |
221 _handleFileOrDirectoryRequest(request, allowedPort); | 221 _handleFileOrDirectoryRequest(request, allowedPort); |
222 } | 222 } |
223 | 223 |
224 server.addHandler('/$PREFIX_BUILDDIR', fileHandler); | 224 server.addHandler('/$PREFIX_BUILDDIR', fileHandler); |
225 server.addHandler('/$PREFIX_DARTDIR', fileHandler); | 225 server.addHandler('/$PREFIX_DARTDIR', fileHandler); |
226 server.addHandler('/packages', fileHandler); | 226 server.addHandler('/packages', fileHandler); |
227 _serverList.add(httpServer); | 227 _serverList.add(httpServer); |
228 return server; | 228 return server; |
229 }); | 229 }); |
230 } | 230 } |
231 | 231 |
232 _handleFileOrDirectoryRequest(HttpRequest request, int allowedPort) async { | 232 Future _handleFileOrDirectoryRequest( |
| 233 HttpRequest request, int allowedPort) async { |
233 // Enable browsers to cache file/directory responses. | 234 // Enable browsers to cache file/directory responses. |
234 var response = request.response; | 235 var response = request.response; |
235 response.headers | 236 response.headers |
236 .set("Cache-Control", "max-age=$_CACHE_EXPIRATION_IN_SECONDS"); | 237 .set("Cache-Control", "max-age=$_CACHE_EXPIRATION_IN_SECONDS"); |
237 var path = _getFileUriFromRequestUri(request.uri); | 238 var path = _getFileUriFromRequestUri(request.uri); |
238 if (path != null) { | 239 if (path != null) { |
239 var file = new File.fromUri(path); | 240 var file = new File.fromUri(path); |
240 var directory = new Directory.fromUri(path); | 241 var directory = new Directory.fromUri(path); |
241 if (await file.exists()) { | 242 if (await file.exists()) { |
242 _sendFileContent(request, response, allowedPort, file); | 243 _sendFileContent(request, response, allowedPort, file); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 if (pathSegments[0] == PREFIX_BUILDDIR) { | 306 if (pathSegments[0] == PREFIX_BUILDDIR) { |
306 return _buildDirectory.resolve(pathSegments.skip(1).join('/')); | 307 return _buildDirectory.resolve(pathSegments.skip(1).join('/')); |
307 } | 308 } |
308 if (pathSegments[0] == PREFIX_DARTDIR) { | 309 if (pathSegments[0] == PREFIX_DARTDIR) { |
309 return _dartDirectory.resolve(pathSegments.skip(1).join('/')); | 310 return _dartDirectory.resolve(pathSegments.skip(1).join('/')); |
310 } | 311 } |
311 return null; | 312 return null; |
312 } | 313 } |
313 | 314 |
314 Future<List<_Entry>> _listDirectory(Directory directory) { | 315 Future<List<_Entry>> _listDirectory(Directory directory) { |
315 var completer = new Completer(); | 316 var completer = new Completer<List<_Entry>>(); |
316 var entries = []; | 317 var entries = <_Entry>[]; |
317 | 318 |
318 directory.list().listen((FileSystemEntity fse) { | 319 directory.list().listen((FileSystemEntity fse) { |
319 var segments = fse.uri.pathSegments; | 320 var segments = fse.uri.pathSegments; |
320 if (fse is File) { | 321 if (fse is File) { |
321 var filename = segments.last; | 322 var filename = segments.last; |
322 entries.add(new _Entry(filename, filename)); | 323 entries.add(new _Entry(filename, filename)); |
323 } else if (fse is Directory) { | 324 } else if (fse is Directory) { |
324 var dirname = segments[segments.length - 2]; | 325 var dirname = segments[segments.length - 2]; |
325 entries.add(new _Entry(dirname, '$dirname/')); | 326 entries.add(new _Entry(dirname, '$dirname/')); |
326 } | 327 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 response.done.catchError((e) { | 361 response.done.catchError((e) { |
361 DebugLogger.warning( | 362 DebugLogger.warning( |
362 'HttpServer: error while closing the response stream', e); | 363 'HttpServer: error while closing the response stream', e); |
363 }); | 364 }); |
364 } | 365 } |
365 | 366 |
366 void _sendFileContent( | 367 void _sendFileContent( |
367 HttpRequest request, HttpResponse response, int allowedPort, File file) { | 368 HttpRequest request, HttpResponse response, int allowedPort, File file) { |
368 if (allowedPort != -1) { | 369 if (allowedPort != -1) { |
369 var headerOrigin = request.headers.value('Origin'); | 370 var headerOrigin = request.headers.value('Origin'); |
370 var allowedOrigin; | 371 String allowedOrigin; |
371 if (headerOrigin != null) { | 372 if (headerOrigin != null) { |
372 var origin = Uri.parse(headerOrigin); | 373 var origin = Uri.parse(headerOrigin); |
373 // Allow loading from http://*:$allowedPort in browsers. | 374 // Allow loading from http://*:$allowedPort in browsers. |
374 allowedOrigin = '${origin.scheme}://${origin.host}:${allowedPort}'; | 375 allowedOrigin = '${origin.scheme}://${origin.host}:${allowedPort}'; |
375 } else { | 376 } else { |
376 // IE10 appears to be bugged and is not sending the Origin header | 377 // IE10 appears to be bugged and is not sending the Origin header |
377 // when making CORS requests to the same domain but different port. | 378 // when making CORS requests to the same domain but different port. |
378 allowedOrigin = '*'; | 379 allowedOrigin = '*'; |
379 } | 380 } |
380 | 381 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 class _Entry implements Comparable<_Entry> { | 464 class _Entry implements Comparable<_Entry> { |
464 final String name; | 465 final String name; |
465 final String displayName; | 466 final String displayName; |
466 | 467 |
467 _Entry(this.name, this.displayName); | 468 _Entry(this.name, this.displayName); |
468 | 469 |
469 int compareTo(_Entry other) { | 470 int compareTo(_Entry other) { |
470 return name.compareTo(other.name); | 471 return name.compareTo(other.name); |
471 } | 472 } |
472 } | 473 } |
OLD | NEW |