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 |