Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
|
Bob Nystrom
2016/02/03 18:40:41
2016 🎉
nweiz
2016/02/03 20:13:23
Done.
| |
| 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. | |
| 4 | |
| 5 import 'dart:async'; | |
| 6 import 'dart:io'; | |
| 7 | |
| 8 import 'package:path/path.dart' as p; | |
| 9 import 'package:pub/src/utils.dart'; | |
| 10 import 'package:scheduled_test/scheduled_test.dart' hide fail; | |
| 11 import 'package:shelf/shelf.dart' as shelf; | |
| 12 import 'package:shelf/shelf_io.dart' as shelf_io; | |
| 13 | |
| 14 import 'descriptor.dart' as d; | |
| 15 | |
| 16 /// The global [DescriptorServer] that's used by default. | |
| 17 /// | |
| 18 /// `null` if there's no global server in use. This can be set to replace the | |
| 19 /// existing global server. | |
| 20 DescriptorServer get globalServer => _globalServer; | |
| 21 set globalServer(DescriptorServer value) { | |
| 22 if (_globalServer == null) { | |
| 23 currentSchedule.onComplete.schedule(() { | |
| 24 _globalServer = null; | |
| 25 }, 'clearing the global server'); | |
| 26 } else { | |
| 27 _globalServer.close(); | |
| 28 } | |
| 29 | |
| 30 _globalServer = value; | |
| 31 } | |
| 32 DescriptorServer _globalServer; | |
| 33 | |
| 34 /// Creates a global [DescriptorServer] to serve [contents] as static files. | |
| 35 /// | |
| 36 /// This server will exist only for the duration of the pub run. It's accessible | |
| 37 /// via [server]. Subsequent calls to [serve] replace the previous server. | |
| 38 void serve([List<d.Descriptor> contents]) { | |
| 39 globalServer = new DescriptorServer(contents); | |
| 40 } | |
| 41 | |
| 42 /// Like [serve], but reports an error if a request ever comes in to the server. | |
| 43 void serveErrors() { | |
|
Bob Nystrom
2016/02/03 18:40:41
What do you think of "serveNothing"?
nweiz
2016/02/03 20:13:23
It's important that this doesn't just serve 404s,
| |
| 44 globalServer = new DescriptorServer.errors(); | |
| 45 } | |
| 46 | |
| 47 class DescriptorServer { | |
| 48 /// The server, or `null` until it's available. | |
|
Bob Nystrom
2016/02/03 18:40:41
"until" -> "before".
nweiz
2016/02/03 20:13:23
Done.
| |
| 49 HttpServer _server; | |
| 50 | |
| 51 /// A future that will complete to the port used for the server. | |
| 52 Future<int> get port => _portCompleter.future; | |
| 53 final _portCompleter = new Completer<int>(); | |
| 54 | |
| 55 /// Gets the list of paths that have been requested from the server. | |
| 56 Future<List<String>> get requestedPaths => | |
| 57 schedule(() => _requestedPaths.toList(), | |
| 58 "get previous network requests"); | |
| 59 | |
| 60 /// The list of paths that have been requested from this server. | |
| 61 final _requestedPaths = <String>[]; | |
| 62 | |
| 63 /// Creates an HTTP server to serve [contents] as static files. | |
| 64 /// | |
| 65 /// This server will exist only for the duration of the pub run. Subsequent | |
|
Bob Nystrom
2016/02/03 18:40:41
"will exist" -> "exists".
nweiz
2016/02/03 20:13:23
Done.
| |
| 66 /// calls to [serve] replace the previous server. | |
| 67 DescriptorServer([List<d.Descriptor> contents]) { | |
| 68 var baseDir = d.dir("serve-dir", contents); | |
| 69 | |
| 70 schedule(() async { | |
| 71 _server = await shelf_io.serve((request) async { | |
| 72 var path = p.posix.fromUri(request.url.path); | |
| 73 _requestedPaths.add(path); | |
| 74 | |
| 75 try { | |
| 76 var stream = await validateStream(baseDir.load(path)); | |
| 77 return new shelf.Response.ok(stream); | |
| 78 } catch (_) { | |
| 79 return new shelf.Response.notFound('File "$path" not found.'); | |
| 80 } | |
| 81 }, 'localhost', 0); | |
| 82 | |
| 83 _portCompleter.complete(_server.port); | |
| 84 _closeOnComplete(); | |
| 85 }, 'starting a server serving:\n${baseDir.describe()}'); | |
| 86 } | |
| 87 | |
| 88 /// Creates a server that reports an error if a request is ever received. | |
| 89 DescriptorServer.errors() { | |
| 90 schedule(() async { | |
| 91 _server = await shelf_io.serve((request) { | |
| 92 fail("The HTTP server received an unexpected request:\n" | |
| 93 "${request.method} ${request.requestedUri}"); | |
| 94 return new shelf.Response.forbidden(null); | |
| 95 }, 'localhost', 0); | |
| 96 | |
| 97 _portCompleter.complete(_server.port); | |
| 98 _closeOnComplete(); | |
| 99 }); | |
| 100 } | |
| 101 | |
| 102 /// Schedules [requestedPaths] to be emptied. | |
| 103 void clearRequestedPaths() { | |
| 104 schedule(() { | |
| 105 _requestedPaths.clear(); | |
| 106 }, "clearing requested paths"); | |
| 107 } | |
| 108 | |
| 109 /// Schedules the closing of this server. | |
| 110 void close() { | |
| 111 schedule(() async { | |
| 112 if (_server == null) return; | |
| 113 await _server.close(); | |
| 114 }, "closing DescriptorServer"); | |
| 115 } | |
| 116 | |
| 117 /// Schedules this server to close once the schedule is done. | |
| 118 void _closeOnComplete() { | |
| 119 currentSchedule.onComplete.schedule(() async { | |
| 120 if (_server == null) return; | |
| 121 await _server.close(); | |
| 122 }, "closing DescriptorServer"); | |
| 123 } | |
| 124 } | |
| OLD | NEW |