Index: services/mojo_url_redirector/__mojo__.py |
diff --git a/services/mojo_url_redirector/__mojo__.py b/services/mojo_url_redirector/__mojo__.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c0b843dda3699d65df9a23b3b7f0bb4529a382d5 |
--- /dev/null |
+++ b/services/mojo_url_redirector/__mojo__.py |
@@ -0,0 +1,143 @@ |
+# Copyright 2015 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Application that serves requests for Mojo apps and responds with redirects |
+to the locations of the most recent versions of these apps.""" |
+ |
+import http_request_mojom |
+import http_response_mojom |
+import http_server_mojom |
+import http_server_factory_mojom |
+import os |
qsr
2015/02/25 15:34:07
Maybe move this in its own section.
blundell
2015/02/26 13:29:52
Done.
|
+import net_address_mojom |
+import network_service_mojom |
+import service_provider_mojom |
+import url_loader_mojom |
+ |
+from mojo_application import application_delegate |
+from mojo_application import application_impl |
+from mojo_application import application_runner |
+ |
+from mojo_bindings import promise |
+import mojo_system |
+from mojo_utils import data_pipe_utils |
+ |
qsr
2015/02/25 15:34:07
2 blank lines.
blundell
2015/02/26 13:29:52
Done.
|
+class MojoUrlRedirector(http_server_mojom.HttpHandler): |
+ def __init__(self, network_service): |
+ self.network_service = network_service |
+ |
+ def HandleRequest(self, request): |
+ print "Handling request for", request.relative_url |
+ |
+ # Parse the components of the request. |
+ relative_url_components = request.relative_url.split("/") |
+ |
+ # The request must have a component for the platform and for the app. |
+ if len(relative_url_components) != 3: |
+ response = http_response_mojom.HttpResponse() |
+ response.status_code = 400 |
qsr
2015/02/25 15:34:07
Why isn't this a 404
blundell
2015/02/26 13:29:53
400 is "Bad Request": "The server cannot or will n
|
+ return response |
+ |
+ requested_platform = relative_url_components[1] |
+ requested_app = relative_url_components[2] |
+ |
+ print "Request is for", requested_app, "on", requested_platform |
+ return self.FindAppLocation(requested_platform, requested_app) |
+ |
+ def FindAppLocation(self, requested_platform, requested_app): |
+ # Construct a URLRequest to fetch the app location file... |
+ app_location_request = url_loader_mojom.UrlRequest() |
+ mojo_services_url = "https://storage.googleapis.com/mojo/services" |
+ app_name = os.path.splitext(requested_app)[0] |
qsr
2015/02/25 15:34:07
You can write this as:
app_name, _ = os.path.split
blundell
2015/02/26 13:29:53
Done.
|
+ app_location_request.url = "%s/%s/%s_location" % (mojo_services_url, |
+ requested_platform, |
+ app_name) |
+ app_location_request.auto_follow_redirects = True |
+ |
+ # ...and start a URLLoader to fetch it. |
+ url_loader_proxy, request = url_loader_mojom.UrlLoader.manager.NewRequest() |
+ self.network_service.CreateUrlLoader(request) |
+ |
+ # Pass the URLLoader proxy to the callback to ensure that the pipe doesn't |
+ # get closed before the callback runs. |
+ on_version_fetched = lambda response: self.OnFoundAppLocation( |
qsr
2015/02/25 15:34:07
You might want to use functools.partial instead. Y
blundell
2015/02/26 13:29:52
Done.
|
+ response, requested_platform, requested_app, url_loader_proxy) |
+ |
+ print "Calling URL Loader to start" |
+ return url_loader_proxy.Start(app_location_request).Then( |
+ onFullfilled=on_version_fetched) |
qsr
2015/02/25 15:34:07
Do you want to have an onRejected with some loggin
blundell
2015/02/26 13:29:52
Done.
|
+ |
+ def OnFoundAppLocation(self, app_location_response, requested_platform, |
+ requested_app, url_loader_proxy): |
+ print "Load completed" |
+ |
+ response = http_response_mojom.HttpResponse() |
+ response.status_code = 404 |
qsr
2015/02/25 15:34:07
What about a function returning this, and calling
blundell
2015/02/26 13:29:52
Done.
|
+ |
+ if app_location_response.error: |
+ print "Error fetching app location:", app_location_response.error |
+ return response |
+ |
+ if app_location_response.status_code != 200: |
+ print "Unexpected http status in response to fetch of app location:", |
+ print app_location_response.status_code |
+ return response |
+ |
+ # Read out the location of the app. |
+ status, app_location = data_pipe_utils.BlockingCopyFromDataPipeIntoString( |
+ app_location_response.body, 30 * 10**6) |
+ print status |
+ print app_location |
+ if status != mojo_system.RESULT_OK: |
+ print "Error reading app location:", status |
+ return response |
+ print "App location is", app_location |
+ |
+ return self.RedirectToApp(requested_platform, requested_app, app_location) |
+ |
+ def RedirectToApp(self, requested_platform, requested_app, app_location): |
+ response = http_response_mojom.HttpResponse() |
+ print "Redirecting to", app_location |
+ response.status_code = 302 |
+ custom_headers = {} |
+ custom_headers["location"] = app_location |
+ response.custom_headers = custom_headers |
+ return response |
+ |
+ |
+class MojoUrlRedirectorApp(application_delegate.ApplicationDelegate): |
+ def Initialize(self, shell, application): |
+ server_address = net_address_mojom.NetAddress() |
+ server_address.family = net_address_mojom.NetAddressFamily.IPV4 |
+ server_address.ipv4 = net_address_mojom.NetAddressIPv4() |
+ server_address.ipv4.addr = [0, 0, 0, 0] |
+ server_address.ipv4.port = 80 |
+ |
+ # Parse args if given. |
+ if len(application.args) > 1: |
+ assert len(application.args) == 2 |
+ server_address_arg = application.args[1] |
+ server_address_str, server_port_str = server_address_arg.split(":") |
+ server_address.ipv4.addr = [int(n) for n in server_address_str.split(".")] |
+ server_address.ipv4.port = int(server_port_str) |
+ |
+ # Connect to HttpServer. |
+ http_server_factory = application.ConnectToService("mojo:http_server", |
+ http_server_factory_mojom.HttpServerFactory) |
+ self.http_server, request = \ |
+ http_server_mojom.HttpServer.manager.NewRequest() |
+ http_server_factory.CreateHttpServer(request, server_address) |
+ |
+ # Connect to NetworkService. |
+ self.network_service = application.ConnectToService("mojo:network_service", |
+ network_service_mojom.NetworkService) |
+ |
+ # Construct a MojoUrlRedirector and add that as a handler to the server. |
+ self.app_request_handler = MojoUrlRedirector(self.network_service) |
+ self.http_server.SetHandler("/.*", self.app_request_handler) |
+ |
+ |
+def MojoMain(app_request_handle): |
+ application_runner.RunMojoApplication(MojoUrlRedirectorApp(), |
+ app_request_handle) |