Index: tools/telemetry/third_party/gsutil/third_party/protorpc/protorpc/wsgi/service.py |
diff --git a/tools/telemetry/third_party/gsutil/third_party/protorpc/protorpc/wsgi/service.py b/tools/telemetry/third_party/gsutil/third_party/protorpc/protorpc/wsgi/service.py |
deleted file mode 100644 |
index bc1377e93546f0f731f8d819d51f2444b489e9bf..0000000000000000000000000000000000000000 |
--- a/tools/telemetry/third_party/gsutil/third_party/protorpc/protorpc/wsgi/service.py |
+++ /dev/null |
@@ -1,268 +0,0 @@ |
-#!/usr/bin/env python |
-# |
-# Copyright 2011 Google Inc. |
-# |
-# Licensed under the Apache License, Version 2.0 (the "License"); |
-# you may not use this file except in compliance with the License. |
-# You may obtain a copy of the License at |
-# |
-# http://www.apache.org/licenses/LICENSE-2.0 |
-# |
-# Unless required by applicable law or agreed to in writing, software |
-# distributed under the License is distributed on an "AS IS" BASIS, |
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-# See the License for the specific language governing permissions and |
-# limitations under the License. |
-# |
- |
-"""ProtoRPC WSGI service applications. |
- |
-Use functions in this module to configure ProtoRPC services for use with |
-WSGI applications. For more information about WSGI, please see: |
- |
- http://wsgi.org/wsgi |
- http://docs.python.org/library/wsgiref.html |
-""" |
-import six |
- |
-__author__ = 'rafek@google.com (Rafe Kaplan)' |
- |
-import cgi |
-import six.moves.http_client |
-import logging |
-import re |
- |
-from .. import messages |
-from .. import registry |
-from .. import remote |
-from .. import util |
-from . import util as wsgi_util |
- |
-__all__ = [ |
- 'DEFAULT_REGISTRY_PATH', |
- 'service_app', |
-] |
- |
-_METHOD_PATTERN = r'(?:\.([^?]+))' |
-_REQUEST_PATH_PATTERN = r'^(%%s)%s$' % _METHOD_PATTERN |
- |
-_HTTP_BAD_REQUEST = wsgi_util.error(six.moves.http_client.BAD_REQUEST) |
-_HTTP_NOT_FOUND = wsgi_util.error(six.moves.http_client.NOT_FOUND) |
-_HTTP_UNSUPPORTED_MEDIA_TYPE = wsgi_util.error(six.moves.http_client.UNSUPPORTED_MEDIA_TYPE) |
- |
-DEFAULT_REGISTRY_PATH = '/protorpc' |
- |
- |
-@util.positional(2) |
-def service_mapping(service_factory, service_path=r'.*', protocols=None): |
- """WSGI application that handles a single ProtoRPC service mapping. |
- |
- Args: |
- service_factory: Service factory for creating instances of service request |
- handlers. Either callable that takes no parameters and returns a service |
- instance or a service class whose constructor requires no parameters. |
- service_path: Regular expression for matching requests against. Requests |
- that do not have matching paths will cause a 404 (Not Found) response. |
- protocols: remote.Protocols instance that configures supported protocols |
- on server. |
- """ |
- service_class = getattr(service_factory, 'service_class', service_factory) |
- remote_methods = service_class.all_remote_methods() |
- path_matcher = re.compile(_REQUEST_PATH_PATTERN % service_path) |
- |
- def protorpc_service_app(environ, start_response): |
- """Actual WSGI application function.""" |
- path_match = path_matcher.match(environ['PATH_INFO']) |
- if not path_match: |
- return _HTTP_NOT_FOUND(environ, start_response) |
- service_path = path_match.group(1) |
- method_name = path_match.group(2) |
- |
- content_type = environ.get('CONTENT_TYPE') |
- if not content_type: |
- content_type = environ.get('HTTP_CONTENT_TYPE') |
- if not content_type: |
- return _HTTP_BAD_REQUEST(environ, start_response) |
- |
- # TODO(rafek): Handle alternate encodings. |
- content_type = cgi.parse_header(content_type)[0] |
- |
- request_method = environ['REQUEST_METHOD'] |
- if request_method != 'POST': |
- content = ('%s.%s is a ProtoRPC method.\n\n' |
- 'Service %s\n\n' |
- 'More about ProtoRPC: ' |
- '%s\n' % |
- (service_path, |
- method_name, |
- service_class.definition_name().encode('utf-8'), |
- util.PROTORPC_PROJECT_URL)) |
- error_handler = wsgi_util.error( |
- six.moves.http_client.METHOD_NOT_ALLOWED, |
- six.moves.http_client.responses[six.moves.http_client.METHOD_NOT_ALLOWED], |
- content=content, |
- content_type='text/plain; charset=utf-8') |
- return error_handler(environ, start_response) |
- |
- local_protocols = protocols or remote.Protocols.get_default() |
- try: |
- protocol = local_protocols.lookup_by_content_type(content_type) |
- except KeyError: |
- return _HTTP_UNSUPPORTED_MEDIA_TYPE(environ,start_response) |
- |
- def send_rpc_error(status_code, state, message, error_name=None): |
- """Helper function to send an RpcStatus message as response. |
- |
- Will create static error handler and begin response. |
- |
- Args: |
- status_code: HTTP integer status code. |
- state: remote.RpcState enum value to send as response. |
- message: Helpful message to send in response. |
- error_name: Error name if applicable. |
- |
- Returns: |
- List containing encoded content response using the same content-type as |
- the request. |
- """ |
- status = remote.RpcStatus(state=state, |
- error_message=message, |
- error_name=error_name) |
- encoded_status = protocol.encode_message(status) |
- error_handler = wsgi_util.error( |
- status_code, |
- content_type=protocol.default_content_type, |
- content=encoded_status) |
- return error_handler(environ, start_response) |
- |
- method = remote_methods.get(method_name) |
- if not method: |
- return send_rpc_error(six.moves.http_client.BAD_REQUEST, |
- remote.RpcState.METHOD_NOT_FOUND_ERROR, |
- 'Unrecognized RPC method: %s' % method_name) |
- |
- content_length = int(environ.get('CONTENT_LENGTH') or '0') |
- |
- remote_info = method.remote |
- try: |
- request = protocol.decode_message( |
- remote_info.request_type, environ['wsgi.input'].read(content_length)) |
- except (messages.ValidationError, messages.DecodeError) as err: |
- return send_rpc_error(six.moves.http_client.BAD_REQUEST, |
- remote.RpcState.REQUEST_ERROR, |
- 'Error parsing ProtoRPC request ' |
- '(Unable to parse request content: %s)' % err) |
- |
- instance = service_factory() |
- |
- initialize_request_state = getattr( |
- instance, 'initialize_request_state', None) |
- if initialize_request_state: |
- # TODO(rafek): This is not currently covered by tests. |
- server_port = environ.get('SERVER_PORT', None) |
- if server_port: |
- server_port = int(server_port) |
- |
- headers = [] |
- for name, value in six.iteritems(environ): |
- if name.startswith('HTTP_'): |
- headers.append((name[len('HTTP_'):].lower().replace('_', '-'), value)) |
- request_state = remote.HttpRequestState( |
- remote_host=environ.get('REMOTE_HOST', None), |
- remote_address=environ.get('REMOTE_ADDR', None), |
- server_host=environ.get('SERVER_HOST', None), |
- server_port=server_port, |
- http_method=request_method, |
- service_path=service_path, |
- headers=headers) |
- |
- initialize_request_state(request_state) |
- |
- try: |
- response = method(instance, request) |
- encoded_response = protocol.encode_message(response) |
- except remote.ApplicationError as err: |
- return send_rpc_error(six.moves.http_client.BAD_REQUEST, |
- remote.RpcState.APPLICATION_ERROR, |
- err.message, |
- err.error_name) |
- except Exception as err: |
- logging.exception('Encountered unexpected error from ProtoRPC ' |
- 'method implementation: %s (%s)' % |
- (err.__class__.__name__, err)) |
- return send_rpc_error(six.moves.http_client.INTERNAL_SERVER_ERROR, |
- remote.RpcState.SERVER_ERROR, |
- 'Internal Server Error') |
- |
- response_headers = [('content-type', content_type)] |
- start_response('%d %s' % (six.moves.http_client.OK, six.moves.http_client.responses[six.moves.http_client.OK],), |
- response_headers) |
- return [encoded_response] |
- |
- # Return WSGI application. |
- return protorpc_service_app |
- |
- |
-@util.positional(1) |
-def service_mappings(services, registry_path=DEFAULT_REGISTRY_PATH): |
- """Create multiple service mappings with optional RegistryService. |
- |
- Use this function to create single WSGI application that maps to |
- multiple ProtoRPC services plus an optional RegistryService. |
- |
- Example: |
- services = service.service_mappings( |
- [(r'/time', TimeService), |
- (r'/weather', WeatherService) |
- ]) |
- |
- In this example, the services WSGI application will map to two services, |
- TimeService and WeatherService to the '/time' and '/weather' paths |
- respectively. In addition, it will also add a ProtoRPC RegistryService |
- configured to serve information about both services at the (default) path |
- '/protorpc'. |
- |
- Args: |
- services: If a dictionary is provided instead of a list of tuples, the |
- dictionary item pairs are used as the mappings instead. |
- Otherwise, a list of tuples (service_path, service_factory): |
- service_path: The path to mount service on. |
- service_factory: A service class or service instance factory. |
- registry_path: A string to change where the registry is mapped (the default |
- location is '/protorpc'). When None, no registry is created or mounted. |
- |
- Returns: |
- WSGI application that serves ProtoRPC services on their respective URLs |
- plus optional RegistryService. |
- """ |
- if isinstance(services, dict): |
- services = six.iteritems(services) |
- |
- final_mapping = [] |
- paths = set() |
- registry_map = {} if registry_path else None |
- |
- for service_path, service_factory in services: |
- try: |
- service_class = service_factory.service_class |
- except AttributeError: |
- service_class = service_factory |
- |
- if service_path not in paths: |
- paths.add(service_path) |
- else: |
- raise remote.ServiceConfigurationError( |
- 'Path %r is already defined in service mapping' % |
- service_path.encode('utf-8')) |
- |
- if registry_map is not None: |
- registry_map[service_path] = service_class |
- |
- final_mapping.append(service_mapping(service_factory, service_path)) |
- |
- if registry_map is not None: |
- final_mapping.append(service_mapping( |
- registry.RegistryService.new_factory(registry_map), registry_path)) |
- |
- return wsgi_util.first_found(final_mapping) |
- |