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

Unified Diff: third_party/google-endpoints/endpoints/api_request.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 11 months 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 side-by-side diff with in-line comments
Download patch
Index: third_party/google-endpoints/endpoints/api_request.py
diff --git a/third_party/google-endpoints/endpoints/api_request.py b/third_party/google-endpoints/endpoints/api_request.py
new file mode 100644
index 0000000000000000000000000000000000000000..3fc5764c57d0d05c0044f0d4d5164d95e69eac63
--- /dev/null
+++ b/third_party/google-endpoints/endpoints/api_request.py
@@ -0,0 +1,151 @@
+# Copyright 2016 Google Inc. All Rights Reserved.
+#
+# 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.
+
+"""Cloud Endpoints API request-related data and functions."""
+
+from __future__ import with_statement
+
+# pylint: disable=g-bad-name
+import copy
+import json
+import logging
+import urllib
+import urlparse
+import zlib
+
+import util
+
+
+class ApiRequest(object):
+ """Simple data object representing an API request.
+
+ Parses the request from environment variables into convenient pieces
+ and stores them as members.
+ """
+ def __init__(self, environ, base_paths=None):
+ """Constructor.
+
+ Args:
+ environ: An environ dict for the request as defined in PEP-333.
+
+ Raises:
+ ValueError: If the path for the request is invalid.
+ """
+ self.headers = util.get_headers_from_environ(environ)
+ self.http_method = environ['REQUEST_METHOD']
+ self.url_scheme = environ['wsgi.url_scheme']
+ self.server = environ['SERVER_NAME']
+ self.port = environ['SERVER_PORT']
+ self.path = environ['PATH_INFO']
+ self.query = environ.get('QUERY_STRING')
+ self.body = environ['wsgi.input'].read()
+ if self.body and self.headers.get('CONTENT-ENCODING') == 'gzip':
+ # Increasing wbits to 16 + MAX_WBITS is necessary to be able to decode
+ # gzipped content (as opposed to zlib-encoded content).
+ # If there's an error in the decompression, it could be due to another
+ # part of the serving chain that already decompressed it without clearing
+ # the header. If so, just ignore it and continue.
+ try:
+ self.body = zlib.decompress(self.body, 16 + zlib.MAX_WBITS)
+ except zlib.error:
+ pass
+ self.source_ip = environ.get('REMOTE_ADDR')
+ self.relative_url = self._reconstruct_relative_url(environ)
+
+ if not base_paths:
+ base_paths = set()
+ elif isinstance(base_paths, list):
+ base_paths = set(base_paths)
+
+ # Find a base_path in the path
+ for base_path in base_paths:
+ if self.path.startswith(base_path):
+ self.path = self.path[len(base_path):]
+ self.base_path = base_path
+ break
+ else:
+ raise ValueError('Invalid request path: %s' % self.path)
+
+ if self.query:
+ self.parameters = urlparse.parse_qs(self.query, keep_blank_values=True)
+ else:
+ self.parameters = {}
+ self.body_json = self._process_req_body(self.body) if self.body else {}
+ self.request_id = None
+
+ # Check if it's a batch request. We'll only handle single-element batch
+ # requests on the dev server (and we need to handle them because that's
+ # what RPC and JS calls typically show up as). Pull the request out of the
+ # list and record the fact that we're processing a batch.
+ if isinstance(self.body_json, list):
+ if len(self.body_json) != 1:
+ logging.warning('Batch requests with more than 1 element aren\'t '
+ 'supported in devappserver2. Only the first element '
+ 'will be handled. Found %d elements.',
+ len(self.body_json))
+ else:
+ logging.info('Converting batch request to single request.')
+ self.body_json = self.body_json[0]
+ self.body = json.dumps(self.body_json)
+ self._is_batch = True
+ else:
+ self._is_batch = False
+
+ def _process_req_body(self, body):
+ """Process the body of the HTTP request.
+
+ If the body is valid JSON, return the JSON as a dict.
+ Else, convert the key=value format to a dict and return that.
+
+ Args:
+ body: The body of the HTTP request.
+ """
+ try:
+ return json.loads(body)
+ except ValueError:
+ return urlparse.parse_qs(body, keep_blank_values=True)
+
+ def _reconstruct_relative_url(self, environ):
+ """Reconstruct the relative URL of this request.
+
+ This is based on the URL reconstruction code in Python PEP 333:
+ http://www.python.org/dev/peps/pep-0333/#url-reconstruction. Rebuild the
+ URL from the pieces available in the environment.
+
+ Args:
+ environ: An environ dict for the request as defined in PEP-333.
+
+ Returns:
+ The portion of the URL from the request after the server and port.
+ """
+ url = urllib.quote(environ.get('SCRIPT_NAME', ''))
+ url += urllib.quote(environ.get('PATH_INFO', ''))
+ if environ.get('QUERY_STRING'):
+ url += '?' + environ['QUERY_STRING']
+ return url
+
+ def copy(self):
+ return copy.deepcopy(self)
+
+ def is_rpc(self):
+ # Google's JsonRPC protocol creates a handler at /rpc for any Cloud
+ # Endpoints API, with api name, version, and method name being in the
+ # body of the request.
+ # If the request is sent to /rpc, we will treat it as JsonRPC.
+ # The client libraries for iOS's Objective C use RPC and not the REST
+ # versions of the API.
+ return self.path == 'rpc'
+
+ def is_batch(self):
+ return self._is_batch
« no previous file with comments | « third_party/google-endpoints/endpoints/api_exceptions.py ('k') | third_party/google-endpoints/endpoints/apiserving.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698