def handle_api_static_request(self, request, start_response): """Handler for requests to {base_path}/static/.*. This calls start_response and returns the response body. Args: request: An ApiRequest, the request from the user. start_response: A function with semantics defined in PEP-333. Returns: A string containing the response body. """ discovery_api = discovery_api_proxy.DiscoveryApiProxy() response, body = discovery_api.get_static_file(request.relative_url) status_string = '%d %s' % (response.status, response.reason) if response.status == 200: # Some of the headers that come back from the server can't be passed # along in our response. Specifically, the response from the server has # transfer-encoding: chunked, which doesn't apply to the response that # we're forwarding. There may be other problematic headers, so we strip # off everything but Content-Type. return util.send_wsgi_response(status_string, [('Content-Type', response.getheader('Content-Type'))], body, start_response) else: logging.error('Discovery API proxy failed on %s with %d. Details: %s', request.relative_url, response.status, body) return util.send_wsgi_response(status_string, response.getheaders(), body, start_response)
def _handle_request_error(self, orig_request, error, start_response): """Handle a request error, converting it to a WSGI response. Args: orig_request: An ApiRequest, the original request from the user. error: A RequestError containing information about the error. start_response: A function with semantics defined in PEP-333. Returns: A string containing the response body. """ headers = [('Content-Type', 'application/json')] if orig_request.is_rpc(): # JSON RPC errors are returned with status 200 OK and the # error details in the body. status_code = 200 body = self._finish_rpc_response(orig_request.body_json.get('id'), orig_request.is_batch(), error.rpc_error()) else: status_code = error.status_code() body = error.rest_error() response_status = '%d %s' % ( status_code, httplib.responses.get(status_code, 'Unknown Error')) cors_handler = self._create_cors_handler(orig_request) return util.send_wsgi_response(response_status, headers, body, start_response, cors_handler=cors_handler)
def dispatch_non_api_requests(self, request, start_response): """Dispatch this request if this is a request to a reserved URL. If the request matches one of our reserved URLs, this calls start_response and returns the response body. This also handles OPTIONS CORS requests. Args: request: An ApiRequest, the request from the user. start_response: A function with semantics defined in PEP-333. Returns: None if the request doesn't match one of the reserved URLs this handles. Otherwise, returns the response body. """ for path_regex, dispatch_function in self._dispatchers: if path_regex.match(request.relative_url): return dispatch_function(request, start_response) if request.http_method == 'OPTIONS': cors_handler = self._create_cors_handler(request) if cors_handler.allow_cors_request: # The server returns 200 rather than 204, for some reason. return util.send_wsgi_response('200', [], '', start_response, cors_handler) return None
def _handle_request_error(self, orig_request, error, start_response): """Handle a request error, converting it to a WSGI response. Args: orig_request: An ApiRequest, the original request from the user. error: A RequestError containing information about the error. start_response: A function with semantics defined in PEP-333. Returns: A string containing the response body. """ headers = [('Content-Type', 'application/json')] if orig_request.is_rpc(): # JSON RPC errors are returned with status 200 OK and the # error details in the body. status_code = 200 body = self._finish_rpc_response(orig_request.body_json.get('id'), orig_request.is_batch(), error.rpc_error()) else: status_code = error.status_code() body = error.rest_error() response_status = '%d %s' % (status_code, httplib.responses.get(status_code, 'Unknown Error')) cors_handler = self._create_cors_handler(orig_request) return util.send_wsgi_response(response_status, headers, body, start_response, cors_handler=cors_handler)
def handle_backend_response(self, orig_request, backend_request, response_status, response_headers, response_body, method_config, start_response): """Handle backend response, transforming output as needed. This calls start_response and returns the response body. Args: orig_request: An ApiRequest, the original request from the user. backend_request: An ApiRequest, the transformed request that was sent to the backend handler. response_status: A string, the status from the response. response_headers: A dict, the headers from the response. response_body: A string, the body of the response. method_config: A dict, the API config of the method to be called. start_response: A function with semantics defined in PEP-333. Returns: A string containing the response body. """ # Verify that the response is json. If it isn't treat, the body as an # error message and wrap it in a json error response. for header, value in response_headers: if (header.lower() == 'content-type' and not value.lower().startswith('application/json')): return self.fail_request(orig_request, 'Non-JSON reply: %s' % response_body, start_response) self.check_error_response(response_body, response_status) # Need to check is_rpc() against the original request, because the # incoming request here has had its path modified. if orig_request.is_rpc(): body = self.transform_jsonrpc_response(backend_request, response_body) else: # Check if the response from the API was empty. Empty REST responses # generate a HTTP 204. empty_response = self.check_empty_response(orig_request, method_config, start_response) if empty_response is not None: return empty_response body = self.transform_rest_response(response_body) cors_handler = self._create_cors_handler(orig_request) return util.send_wsgi_response(response_status, response_headers, body, start_response, cors_handler=cors_handler)
def handle_api_static_request(self, request, start_response): """Handler for requests to {base_path}/static/.*. This calls start_response and returns the response body. Args: request: An ApiRequest, the request from the user. start_response: A function with semantics defined in PEP-333. Returns: A string containing the response body. """ if request.path == PROXY_PATH: return util.send_wsgi_response('200 OK', [('Content-Type', 'text/html')], PROXY_HTML, start_response) else: logging.error('Unknown static url requested: %s', request.relative_url) return util.send_wsgi_response('404 Not Found', [('Content-Type', 'text/plain')], 'Not Found', start_response)
def _send_success_response(self, response, start_response): """Sends an HTTP 200 json success response. This calls start_response and returns the response body. Args: response: A string containing the response body to return. start_response: A function with semantics defined in PEP-333. Returns: A string, the response body. """ headers = [('Content-Type', 'application/json; charset=UTF-8')] return util.send_wsgi_response('200', headers, response, start_response)