示例#1
0
    def check_echo(self, enc):
        headers = self.make_headers(enc)
        headers['Origin'] = 'example.com'
        encoder = encoding.get_encoder(enc)
        req = test_pb2.EchoRequest()
        req.r.m = 94049
        encoded_req = encoder(req)
        if enc == encoding.Encoding.JSON:
            encoded_req = encoded_req[4:]
        http_resp = self.app.post(
            '/prpc/test.Test/Echo',
            encoded_req,
            headers,
        )
        self.check_headers(
            http_resp.headers,
            server.StatusCode.OK,
            origin='example.com',
        )
        self.assertEqual(http_resp.status_int, httplib.OK)
        raw_resp = http_resp.body
        resp = test_pb2.EchoResponse()
        decoder = encoding.get_decoder(enc)
        if enc == encoding.Encoding.JSON:
            raw_resp = raw_resp[4:]
        decoder(raw_resp, resp)

        self.assertEqual(len(resp.response), 2)
        self.assertEqual(resp.response[0], 'hello!')
        self.assertEqual(resp.response[1], '94049')
示例#2
0
def _encode(d):
    # Skip escaping characters.
    raw = encoding.get_encoder(encoding.Encoding.JSON)(d)
    assert raw[:5] == ')]}\'\n', raw[:5]
    return raw[5:]
示例#3
0
      def _handle(self, context, service, method):
        """Generates the response content and sets the context appropriately.

        Sets context._request_encoding and context._response_encoding.

        Args:
          context: a context.ServicerContext.
          service: the service being targeted by this pRPC call.
          method: the method being invoked by this pRPC call.

        Returns:
          content: the binary or textual content of the RPC response. Note
            that this may be None in the event that an error occurs.
        """
        try:
          parsed_headers = headers.parse_headers(self.request.headers)
          context._request_encoding = parsed_headers.content_type
          context._response_encoding = parsed_headers.accept
        except ValueError as e:
          logging.warning('Error parsing headers: %s', e)
          context.set_code(StatusCode.INVALID_ARGUMENT)
          context.set_details(e.message)
          return None

        if service not in server._services:
          context.set_code(StatusCode.UNIMPLEMENTED)
          context.set_details('Service %s does not exist' % service)
          return None
        rpc_handler = server._services[service].methods.get(method)
        if rpc_handler is None:
          context.set_code(StatusCode.UNIMPLEMENTED)
          context.set_details('Method %s does not exist' % method)
          return None
        request_message, response_message, handler = rpc_handler

        request = request_message()
        try:
          decoder = encoding.get_decoder(parsed_headers.content_type)
          decoder(self.request.body, request)
        except Exception as e:
          logging.warning('Failed to decode request: %s', e, exc_info=True)
          context.set_code(StatusCode.INVALID_ARGUMENT)
          context.set_details('Error parsing request: %s' % e.message)
          return None

        context._timeout = parsed_headers.timeout
        context._invocation_metadata = parsed_headers.invocation_metadata

        # Only ipv6 addresses have ':' in them. Assume everything else is ipv4.
        if ':' in self.request.remote_addr:
          context._peer = 'ipv6:[%s]' % self.request.remote_addr
        else:
          context._peer = 'ipv4:%s' % self.request.remote_addr

        call_details = HandlerCallDetails(
            method='%s.%s' % (service, method),
            invocation_metadata=context.invocation_metadata())

        try:
          # TODO(nodir,mknyszek): Poll for context to hit timeout or be
          # canceled.
          response = server._run_interceptors(
              request, context, call_details, handler, 0)
        except Exception:
          logging.exception('Service implementation threw an exception')
          context.set_code(StatusCode.INTERNAL)
          context.set_details('Service implementation threw an exception')
          return None

        if response is None:
          if context._code == StatusCode.OK:
            context.set_code(StatusCode.INTERNAL)
            context.set_details(
                'Service implementation didn\'t return a response')
          return None

        if not isinstance(response, response_message):
          logging.error('Service implementation response has incorrect type')
          context.set_code(StatusCode.INTERNAL)
          context.set_details('Service implementation returned invalid value')
          return None

        try:
          encoder = encoding.get_encoder(parsed_headers.accept)
          content = encoder(response)
        except Exception:
          logging.exception('Failed to encode response')
          context.set_code(StatusCode.INTERNAL)
          context.set_details('Error serializing response')
          return None

        return content