Пример #1
0
  def handle_api_static_request(self, request, start_response):
    """Handler for requests to _ah/api/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)
Пример #2
0
    def handle_api_static_request(self, request, start_response):
        """Handler for requests to _ah/api/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)
Пример #3
0
    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 = EndpointsDispatcher.__CheckCorsHeaders(orig_request)
        return util.send_wsgi_response(response_status,
                                       headers,
                                       body,
                                       start_response,
                                       cors_handler=cors_handler)
Пример #4
0
    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 = EndpointsDispatcher.__CheckCorsHeaders(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
Пример #5
0
  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 = EndpointsDispatcher.__CheckCorsHeaders(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 = EndpointsDispatcher.__CheckCorsHeaders(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_spi_response(self, orig_request, spi_request, response,
                          start_response):
    """Handle SPI 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.
      spi_request: An ApiRequest, the transformed request that was sent to the
        SPI handler.
      response: A ResponseTuple, the response from the SPI handler.
      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.content,
                                 start_response)

    body = response.content
    # 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(spi_request, body)

    cors_handler = EndpointsDispatcher.__CheckCorsHeaders(orig_request)
    return util.send_wsgi_response(response.status, response.headers, body,
                                   start_response, cors_handler=cors_handler)
Пример #8
0
 def test_send_wsgi_response(self):
     mock_headers = [('content-type', 'text/plain')]
     content = 'Test output'
     response = util.send_wsgi_response('200', mock_headers, content,
                                        self.start_response)
     self.assert_http_match(response, 200, [('content-type', 'text/plain'),
                                            ('Content-Length', '11')],
                            content)
Пример #9
0
 def test_send_wsgi_response(self):
   mock_headers = [('content-type', 'text/plain')]
   content = 'Test output'
   response = util.send_wsgi_response(
       '200', mock_headers, content, self.start_response)
   self.assert_http_match(response, 200,
                          [('content-type', 'text/plain'),
                           ('Content-Length', '11')],
                          content)
Пример #10
0
    def handle_spi_response(self, orig_request, spi_request, response,
                            method_config, start_response):
        """Handle SPI 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.
      spi_request: An ApiRequest, the transformed request that was sent to the
        SPI handler.
      response: A ResponseTuple, the response from the SPI handler.
      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.content,
                    start_response)

        self.check_error_response(response)

        # 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(spi_request,
                                                   response.content)
        else:
            # Check if the response from the SPI 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.content)

        cors_handler = EndpointsDispatcher.__CheckCorsHeaders(orig_request)
        return util.send_wsgi_response(response.status,
                                       response.headers,
                                       body,
                                       start_response,
                                       cors_handler=cors_handler)
  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)
Пример #12
0
    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)
Пример #13
0
 def test_send_wsgi_response(self):
     mock_headers = [("content-type", "text/plain")]
     content = "Test output"
     response = util.send_wsgi_response("200", mock_headers, content, self.start_response)
     self.assert_http_match(response, 200, [("content-type", "text/plain"), ("Content-Length", "11")], content)