Skip to content

Commit

Permalink
[ VM / Service ] Handle case where user navigates to Observatory with…
Browse files Browse the repository at this point in the history
…out a slash trailing the authentication code.

Previously, navigating to an observatory URI similar to http://127.0.0.1:8181/KUhS6KoCm24=
would result in a missing auth code error. This change explicitly checks
for this case and issues a redirect response to
http://127.0.0.1:8181/KUhS6KoCm24=/ so index.html can be sent properly
in the follow up request.

Fixes flutter#36763

Change-Id: I8a73f2ef08f6bf1ca5aed4ddaaf97ae3489f7e23
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100631
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
  • Loading branch information
bkonyi authored and commit-bot@chromium.org committed Apr 29, 2019
1 parent 4038f91 commit 2439618
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions runtime/bin/vmservice/server.dart
Expand Up @@ -216,14 +216,15 @@ class Server {
return false;
}

/// Checks the [requestUri] for the service auth token and returns the path.
/// If the service auth token check fails, returns null.
String _checkAuthTokenAndGetPath(Uri requestUri) {
/// Checks the [requestUri] for the service auth token and returns the path
/// as a String. If the service auth token check fails, returns null.
/// Returns a Uri if a redirect is required.
dynamic _checkAuthTokenAndGetPath(Uri requestUri) {
if (_authCodesDisabled) {
return requestUri.path == '/' ? ROOT_REDIRECT_PATH : requestUri.path;
}
final List<String> requestPathSegments = requestUri.pathSegments;
if (requestPathSegments.length < 2) {
if (requestPathSegments.isEmpty) {
// Malformed.
return null;
}
Expand All @@ -233,6 +234,18 @@ class Server {
// Malformed.
return null;
}
// Missing a trailing '/'. We'll need to redirect to serve
// ROOT_REDIRECT_PATH correctly, otherwise the response is misinterpreted.
if (requestPathSegments.length == 1) {
// requestPathSegments is unmodifiable. Copy it.
final List<String> pathSegments = <String>[]..addAll(requestPathSegments);

// Adding an empty string to the path segments results in the path having
// a trailing '/'.
pathSegments.add('');

return requestUri.replace(pathSegments: pathSegments);
}
// Construct the actual request path by chopping off the auth token.
return (requestPathSegments[1] == '')
? ROOT_REDIRECT_PATH
Expand Down Expand Up @@ -305,16 +318,24 @@ class Server {
return;
}

final String path = _checkAuthTokenAndGetPath(request.uri);
if (path == null) {
final dynamic result = _checkAuthTokenAndGetPath(request.uri);
if (result == null) {
// Either no authentication code was provided when one was expected or an
// incorrect authentication code was provided.
request.response.statusCode = HttpStatus.forbidden;
request.response.write("missing or invalid authentication code");
request.response.close();
return;
} else if (result is Uri) {
// The URI contains the valid auth token but is missing a trailing '/'.
// Redirect to the same URI with the trailing '/' to correctly serve
// index.html.
request.response.redirect(result as Uri);
request.response.close();
return;
}

final String path = result;
if (path == WEBSOCKET_PATH) {
WebSocketTransformer.upgrade(request).then((WebSocket webSocket) {
new WebSocketClient(webSocket, _service);
Expand Down

0 comments on commit 2439618

Please sign in to comment.