Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: runtime/bin/vmservice/server.dart

Issue 2438613002: Provide an API to dart:developer to control the web server hosting the Service Protocol (Closed)
Patch Set: CHANGELOG.md merge and fatal error Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « CHANGELOG.md ('k') | runtime/bin/vmservice/vmservice_io.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of vmservice_io; 5 part of vmservice_io;
6 6
7 class WebSocketClient extends Client { 7 class WebSocketClient extends Client {
8 static const int PARSE_ERROR_CODE = 4000; 8 static const int PARSE_ERROR_CODE = 4000;
9 static const int BINARY_MESSAGE_ERROR_CODE = 4001; 9 static const int BINARY_MESSAGE_ERROR_CODE = 4001;
10 static const int NOT_MAP_ERROR_CODE = 4002; 10 static const int NOT_MAP_ERROR_CODE = 4002;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 class Server { 119 class Server {
120 static const WEBSOCKET_PATH = '/ws'; 120 static const WEBSOCKET_PATH = '/ws';
121 static const ROOT_REDIRECT_PATH = '/index.html'; 121 static const ROOT_REDIRECT_PATH = '/index.html';
122 122
123 final VMService _service; 123 final VMService _service;
124 final String _ip; 124 final String _ip;
125 final int _port; 125 final int _port;
126 final bool _originCheckDisabled; 126 final bool _originCheckDisabled;
127 HttpServer _server; 127 HttpServer _server;
128 bool get running => _server != null; 128 bool get running => _server != null;
129 bool _displayMessages = false;
130 129
131 Server(this._service, this._ip, this._port, this._originCheckDisabled) { 130 /// Returns the server address including the auth token.
132 _displayMessages = (_ip != '127.0.0.1' || _port != 8181); 131 Uri get serverAddress {
132 if (!running) {
133 return null;
134 }
135 var ip = _server.address.address;
136 var port = _server.port;
137 if (useAuthToken) {
138 return Uri.parse('http://$ip:$port/$serviceAuthToken/');
139 } else {
140 return Uri.parse('http://$ip:$port/');
141 }
133 } 142 }
134 143
144 Server(this._service, this._ip, this._port, this._originCheckDisabled);
145
135 bool _isAllowedOrigin(String origin) { 146 bool _isAllowedOrigin(String origin) {
136 Uri uri; 147 Uri uri;
137 try { 148 try {
138 uri = Uri.parse(origin); 149 uri = Uri.parse(origin);
139 } catch (_) { 150 } catch (_) {
140 return false; 151 return false;
141 } 152 }
142 153
143 // Explicitly add localhost and 127.0.0.1 on any port (necessary for 154 // Explicitly add localhost and 127.0.0.1 on any port (necessary for
144 // adb port forwarding). 155 // adb port forwarding).
(...skipping 27 matching lines...) Expand all
172 return true; 183 return true;
173 } 184 }
174 for (String origin in origins) { 185 for (String origin in origins) {
175 if (_isAllowedOrigin(origin)) { 186 if (_isAllowedOrigin(origin)) {
176 return true; 187 return true;
177 } 188 }
178 } 189 }
179 return false; 190 return false;
180 } 191 }
181 192
193 /// Checks the [requestUri] for the service auth token and returns the path.
194 /// If the service auth token check fails, returns null.
195 String _checkAuthTokenAndGetPath(Uri requestUri) {
196 if (!useAuthToken) {
197 return requestUri.path == '/' ? ROOT_REDIRECT_PATH : requestUri.path;
198 }
199 final List<String> requestPathSegments = requestUri.pathSegments;
200 if (requestPathSegments.length < 2) {
201 // Malformed.
202 return null;
203 }
204 // Check that we were given the auth token.
205 final String authToken = requestPathSegments[0];
206 if (authToken != serviceAuthToken) {
207 // Malformed.
208 return null;
209 }
210 // Construct the actual request path by chopping off the auth token.
211 return (requestPathSegments[1] == '') ?
212 ROOT_REDIRECT_PATH : '/${requestPathSegments.sublist(1).join('/')}';
213 }
214
182 Future _requestHandler(HttpRequest request) async { 215 Future _requestHandler(HttpRequest request) async {
183 if (!_originCheck(request)) { 216 if (!_originCheck(request)) {
184 // This is a cross origin attempt to connect 217 // This is a cross origin attempt to connect
185 request.response.close(); 218 request.response.close();
186 return; 219 return;
187 } 220 }
188 if (request.method == 'PUT') { 221 if (request.method == 'PUT') {
189 // PUT requests are forwarded to DevFS for processing. 222 // PUT requests are forwarded to DevFS for processing.
190 223
191 List fsNameList; 224 List fsNameList;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 } 257 }
225 request.response.close(); 258 request.response.close();
226 return; 259 return;
227 } 260 }
228 if (request.method != 'GET') { 261 if (request.method != 'GET') {
229 // Not a GET request. Do nothing. 262 // Not a GET request. Do nothing.
230 request.response.close(); 263 request.response.close();
231 return; 264 return;
232 } 265 }
233 266
234 final String path = 267 final String path = _checkAuthTokenAndGetPath(request.uri);
235 request.uri.path == '/' ? ROOT_REDIRECT_PATH : request.uri.path; 268 if (path == null) {
269 // Malformed.
270 request.response.close();
271 return;
272 }
236 273
237 if (path == WEBSOCKET_PATH) { 274 if (path == WEBSOCKET_PATH) {
238 WebSocketTransformer.upgrade(request).then( 275 WebSocketTransformer.upgrade(request).then(
239 (WebSocket webSocket) { 276 (WebSocket webSocket) {
240 new WebSocketClient(webSocket, _service); 277 new WebSocketClient(webSocket, _service);
241 }); 278 });
242 return; 279 return;
243 } 280 }
244 281
245 Asset asset = assets[path]; 282 Asset asset = assets[path];
(...skipping 21 matching lines...) Expand all
267 if (_server != null) { 304 if (_server != null) {
268 // Already running. 305 // Already running.
269 return new Future.value(this); 306 return new Future.value(this);
270 } 307 }
271 308
272 var address = new InternetAddress(_ip); 309 var address = new InternetAddress(_ip);
273 // Startup HTTP server. 310 // Startup HTTP server.
274 return HttpServer.bind(address, _port).then((s) { 311 return HttpServer.bind(address, _port).then((s) {
275 _server = s; 312 _server = s;
276 _server.listen(_requestHandler, cancelOnError: true); 313 _server.listen(_requestHandler, cancelOnError: true);
277 var ip = _server.address.address; 314 print('Observatory listening on $serverAddress');
278 var port = _server.port;
279 if (_displayMessages) {
280 print('Observatory listening on http://$ip:$port');
281 }
282 // Server is up and running. 315 // Server is up and running.
283 _notifyServerState(ip, _server.port); 316 _notifyServerState(serverAddress.toString());
284 onServerAddressChange('http://$ip:$port'); 317 onServerAddressChange('$serverAddress');
285 return this; 318 return this;
286 }).catchError((e, st) { 319 }).catchError((e, st) {
287 print('Could not start Observatory HTTP server:\n$e\n$st\n'); 320 print('Could not start Observatory HTTP server:\n$e\n$st\n');
288 _notifyServerState("", 0); 321 _notifyServerState("");
289 onServerAddressChange(null); 322 onServerAddressChange(null);
290 return this; 323 return this;
291 }); 324 });
292 } 325 }
293 326
294 Future cleanup(bool force) { 327 Future cleanup(bool force) {
295 if (_server == null) { 328 if (_server == null) {
296 return new Future.value(null); 329 return new Future.value(null);
297 } 330 }
298 return _server.close(force: force); 331 return _server.close(force: force);
299 } 332 }
300 333
301 Future shutdown(bool forced) { 334 Future shutdown(bool forced) {
302 if (_server == null) { 335 if (_server == null) {
303 // Not started. 336 // Not started.
304 return new Future.value(this); 337 return new Future.value(this);
305 } 338 }
306 339
307 // Force displaying of status messages if we are forcibly shutdown.
308 _displayMessages = _displayMessages || forced;
309
310 // Shutdown HTTP server and subscription. 340 // Shutdown HTTP server and subscription.
311 var ip = _server.address.address.toString(); 341 String oldServerAddress = serverAddress;
312 var port = _server.port.toString();
313 return cleanup(forced).then((_) { 342 return cleanup(forced).then((_) {
314 if (_displayMessages) { 343 print('Observatory no longer listening on $oldServerAddress');
315 print('Observatory no longer listening on http://$ip:$port');
316 }
317 _server = null; 344 _server = null;
318 _notifyServerState("", 0); 345 _notifyServerState("");
319 onServerAddressChange(null); 346 onServerAddressChange(null);
320 return this; 347 return this;
321 }).catchError((e, st) { 348 }).catchError((e, st) {
322 _server = null; 349 _server = null;
323 print('Could not shutdown Observatory HTTP server:\n$e\n$st\n'); 350 print('Could not shutdown Observatory HTTP server:\n$e\n$st\n');
324 _notifyServerState("", 0); 351 _notifyServerState("");
325 onServerAddressChange(null); 352 onServerAddressChange(null);
326 return this; 353 return this;
327 }); 354 });
328 } 355 }
329 356
330 } 357 }
331 358
332 void _notifyServerState(String ip, int port) 359 void _notifyServerState(String uri)
333 native "VMServiceIO_NotifyServerState"; 360 native "VMServiceIO_NotifyServerState";
OLDNEW
« no previous file with comments | « CHANGELOG.md ('k') | runtime/bin/vmservice/vmservice_io.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698