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 library analysis_server.src.server.http_server; | 5 library analysis_server.src.server.http_server; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
10 import 'package:analysis_server/src/channel/web_socket_channel.dart'; | 10 import 'package:analysis_server/src/channel/web_socket_channel.dart'; |
11 import 'package:analysis_server/src/socket_server.dart'; | 11 import 'package:analysis_server/src/socket_server.dart'; |
12 import 'package:analysis_server/src/status/get_handler.dart'; | 12 import 'package:analysis_server/src/status/get_handler.dart'; |
13 import 'package:analysis_server/src/status/get_handler2.dart'; | 13 import 'package:analysis_server/src/status/get_handler2.dart'; |
14 | 14 |
15 /** | 15 /** |
16 * Instances of the class [HttpServer] implement a simple HTTP server. The | 16 * Instances of the class [HttpServer] implement a simple HTTP server. The |
17 * primary responsibility of this server is to listen for an UPGRADE request and | 17 * server: |
18 * to start an analysis server. | 18 * |
| 19 * - listens for an UPGRADE request in order to start an analysis server |
| 20 * - serves diagnostic information as html pages |
19 */ | 21 */ |
20 class HttpAnalysisServer { | 22 class HttpAnalysisServer { |
21 /** | 23 /** |
22 * Number of lines of print output to capture. | 24 * Number of lines of print output to capture. |
23 */ | 25 */ |
24 static const int MAX_PRINT_BUFFER_LENGTH = 1000; | 26 static const int MAX_PRINT_BUFFER_LENGTH = 1000; |
25 | 27 |
26 /** | 28 /** |
27 * An object that can handle either a WebSocket connection or a connection | 29 * An object that can handle either a WebSocket connection or a connection |
28 * to the client over stdio. | 30 * to the client over stdio. |
(...skipping 13 matching lines...) Expand all Loading... |
42 /** | 44 /** |
43 * Last PRINT_BUFFER_LENGTH lines printed. | 45 * Last PRINT_BUFFER_LENGTH lines printed. |
44 */ | 46 */ |
45 List<String> _printBuffer = <String>[]; | 47 List<String> _printBuffer = <String>[]; |
46 | 48 |
47 /** | 49 /** |
48 * Initialize a newly created HTTP server. | 50 * Initialize a newly created HTTP server. |
49 */ | 51 */ |
50 HttpAnalysisServer(this.socketServer); | 52 HttpAnalysisServer(this.socketServer); |
51 | 53 |
| 54 /** |
| 55 * Return the port this server is bound to. |
| 56 */ |
| 57 Future<int> get boundPort async => (await _server)?.port; |
| 58 |
52 void close() { | 59 void close() { |
53 _server.then((HttpServer server) { | 60 _server.then((HttpServer server) { |
54 server.close(); | 61 server.close(); |
55 }); | 62 }); |
56 } | 63 } |
57 | 64 |
58 /** | 65 /** |
59 * Record that the given line was printed out by the analysis server. | 66 * Record that the given line was printed out by the analysis server. |
60 */ | 67 */ |
61 void recordPrint(String line) { | 68 void recordPrint(String line) { |
62 _printBuffer.add(line); | 69 _printBuffer.add(line); |
63 if (_printBuffer.length > MAX_PRINT_BUFFER_LENGTH) { | 70 if (_printBuffer.length > MAX_PRINT_BUFFER_LENGTH) { |
64 _printBuffer.removeRange( | 71 _printBuffer.removeRange( |
65 0, _printBuffer.length - MAX_PRINT_BUFFER_LENGTH); | 72 0, _printBuffer.length - MAX_PRINT_BUFFER_LENGTH); |
66 } | 73 } |
67 } | 74 } |
68 | 75 |
69 /** | 76 /** |
70 * Begin serving HTTP requests over the given port. | 77 * Begin serving HTTP requests over the given port. |
71 */ | 78 */ |
72 void serveHttp(int port) { | 79 Future<int> serveHttp([int initialPort]) async { |
73 _server = HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, port); | 80 if (_server != null) { |
74 _server.then(_handleServer).catchError((_) {/* Ignore errors. */}); | 81 return boundPort; |
| 82 } |
| 83 |
| 84 try { |
| 85 _server = |
| 86 HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, initialPort ?? 0); |
| 87 HttpServer server = await _server; |
| 88 _handleServer(server); |
| 89 return server.port; |
| 90 } catch (ignore) { |
| 91 return null; |
| 92 } |
75 } | 93 } |
76 | 94 |
77 /** | 95 /** |
78 * Handle a GET request received by the HTTP server. | 96 * Handle a GET request received by the HTTP server. |
79 */ | 97 */ |
80 void _handleGetRequest(HttpRequest request) { | 98 void _handleGetRequest(HttpRequest request) { |
81 if (getHandler == null) { | 99 if (getHandler == null) { |
82 if (socketServer.analysisServer.options.enableNewAnalysisDriver) { | 100 if (socketServer.analysisServer.options.enableNewAnalysisDriver) { |
83 getHandler = new GetHandler2(socketServer, _printBuffer); | 101 getHandler = new GetHandler2(socketServer, _printBuffer); |
84 } else { | 102 } else { |
(...skipping 19 matching lines...) Expand all Loading... |
104 _returnUnknownRequest(request); | 122 _returnUnknownRequest(request); |
105 } | 123 } |
106 }); | 124 }); |
107 } | 125 } |
108 | 126 |
109 /** | 127 /** |
110 * Handle an UPGRADE request received by the HTTP server by creating and | 128 * Handle an UPGRADE request received by the HTTP server by creating and |
111 * running an analysis server on a [WebSocket]-based communication channel. | 129 * running an analysis server on a [WebSocket]-based communication channel. |
112 */ | 130 */ |
113 void _handleWebSocket(WebSocket socket) { | 131 void _handleWebSocket(WebSocket socket) { |
| 132 // TODO(devoncarew): This serves the analysis server over a websocket |
| 133 // connection for historical reasons (and should probably be removed). |
114 socketServer.createAnalysisServer(new WebSocketServerChannel( | 134 socketServer.createAnalysisServer(new WebSocketServerChannel( |
115 socket, socketServer.instrumentationService)); | 135 socket, socketServer.instrumentationService)); |
116 } | 136 } |
117 | 137 |
118 /** | 138 /** |
119 * Return an error in response to an unrecognized request received by the HTTP | 139 * Return an error in response to an unrecognized request received by the HTTP |
120 * server. | 140 * server. |
121 */ | 141 */ |
122 void _returnUnknownRequest(HttpRequest request) { | 142 void _returnUnknownRequest(HttpRequest request) { |
123 HttpResponse response = request.response; | 143 HttpResponse response = request.response; |
124 response.statusCode = HttpStatus.NOT_FOUND; | 144 response.statusCode = HttpStatus.NOT_FOUND; |
125 response.headers.contentType = | 145 response.headers.contentType = |
126 new ContentType("text", "plain", charset: "utf-8"); | 146 new ContentType("text", "plain", charset: "utf-8"); |
127 response.write('Not found'); | 147 response.write('Not found'); |
128 response.close(); | 148 response.close(); |
129 } | 149 } |
130 } | 150 } |
OLD | NEW |