OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_parser/http_parser.dart'; | 8 import 'package:http_parser/http_parser.dart'; |
9 import 'package:shelf/shelf.dart' as shelf; | 9 import 'package:shelf/shelf.dart' as shelf; |
10 import 'package:shelf_web_socket/shelf_web_socket.dart'; | 10 import 'package:shelf_web_socket/shelf_web_socket.dart'; |
11 | 11 |
12 import '../io.dart'; | 12 import '../io.dart'; |
13 import '../log.dart' as log; | 13 import '../log.dart' as log; |
14 import 'asset_environment.dart'; | 14 import 'asset_environment.dart'; |
15 import 'base_server.dart'; | 15 import 'base_server.dart'; |
16 import 'web_socket_api.dart'; | 16 import 'web_socket_api.dart'; |
17 | 17 |
18 /// The web admin interface to pub serve. | 18 /// The web admin interface to pub serve. |
19 // TODO(rnystrom): Currently this just provides access to the Web Socket API. | 19 // TODO(rnystrom): Currently this just provides access to the Web Socket API. |
20 // See #16954. | 20 // See #16954. |
21 class AdminServer extends BaseServer { | 21 class AdminServer extends BaseServer { |
22 /// All currently open [WebSocket] connections. | 22 /// All currently open [WebSocket] connections. |
23 final _webSockets = new Set<CompatibleWebSocket>(); | 23 final _webSockets = new Set<WebSocketChannel>(); |
24 | 24 |
25 shelf.Handler _handler; | 25 shelf.Handler _handler; |
26 | 26 |
27 /// Creates a new server and binds it to [port] of [host]. | 27 /// Creates a new server and binds it to [port] of [host]. |
28 static Future<AdminServer> bind(AssetEnvironment environment, | 28 static Future<AdminServer> bind(AssetEnvironment environment, |
29 String host, int port) { | 29 String host, int port) { |
30 return bindServer(host, port).then((server) { | 30 return bindServer(host, port).then((server) { |
31 log.fine('Bound admin server to $host:$port.'); | 31 log.fine('Bound admin server to $host:$port.'); |
32 return new AdminServer._(environment, server); | 32 return new AdminServer._(environment, server); |
33 }); | 33 }); |
34 } | 34 } |
35 | 35 |
36 AdminServer._(AssetEnvironment environment, HttpServer server) | 36 AdminServer._(AssetEnvironment environment, HttpServer server) |
37 : super(environment, server) { | 37 : super(environment, server) { |
38 _handler = new shelf.Cascade() | 38 _handler = new shelf.Cascade() |
39 .add(webSocketHandler(_handleWebSocket)) | 39 .add(webSocketHandler(_handleWebSocket)) |
40 .add(_handleHttp).handler; | 40 .add(_handleHttp).handler; |
41 } | 41 } |
42 | 42 |
43 /// Closes the server and all Web Socket connections. | 43 /// Closes the server and all Web Socket connections. |
44 Future close() { | 44 Future close() { |
45 var futures = [super.close()]; | 45 var futures = [super.close()]; |
46 futures.addAll(_webSockets.map((socket) => socket.close())); | 46 futures.addAll(_webSockets.map((channel) => channel.sink.close())); |
47 return Future.wait(futures); | 47 return Future.wait(futures); |
48 } | 48 } |
49 | 49 |
50 handleRequest(shelf.Request request) => _handler(request); | 50 handleRequest(shelf.Request request) => _handler(request); |
51 | 51 |
52 /// Handles an HTTP request. | 52 /// Handles an HTTP request. |
53 _handleHttp(shelf.Request request) { | 53 _handleHttp(shelf.Request request) { |
54 // TODO(rnystrom): Actually respond to requests once there is an admin | 54 // TODO(rnystrom): Actually respond to requests once there is an admin |
55 // interface. See #16954. | 55 // interface. See #16954. |
56 logRequest(request, "501 Not Implemented"); | 56 logRequest(request, "501 Not Implemented"); |
57 return new shelf.Response(501, | 57 return new shelf.Response(501, |
58 body: "Currently this server only accepts Web Socket connections."); | 58 body: "Currently this server only accepts Web Socket connections."); |
59 } | 59 } |
60 | 60 |
61 /// Creates a web socket for [request] which should be an upgrade request. | 61 /// Creates a web socket for [request] which should be an upgrade request. |
62 void _handleWebSocket(CompatibleWebSocket socket) { | 62 void _handleWebSocket(WebSocketChannel channel) { |
63 _webSockets.add(socket); | 63 _webSockets.add(channel); |
64 var api = new WebSocketApi(socket, environment); | 64 var api = new WebSocketApi(channel, environment); |
65 api.listen() | 65 api.listen() |
66 .whenComplete(() => _webSockets.remove(api)) | 66 .whenComplete(() => _webSockets.remove(channel)) |
67 .catchError(addError); | 67 .catchError(addError); |
68 } | 68 } |
69 } | 69 } |
OLD | NEW |