def test_403(self):
     self.mock_httplib2([
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({
             'status': 403,
             'reason': 'Auth error'
         }), 'Auth error')),
     ])
     with self.assertRaises(net.AuthError):
         net.request('http://localhost/123')
 def test_404(self):
     self.mock_httplib2([
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({
             'status': 404,
             'reason': 'Not found'
         }), 'Not found')),
     ])
     with self.assertRaises(net.NotFoundError):
         net.request('http://localhost/123')
 def test_legitimate_cloud_endpoints_404_is_not_retried(self):
     self.mock_httplib2([
         ({
             'uri': 'http://localhost/_ah/api/blah'
         }, (httplib2.Response({
             'status': 404,
             'reason': 'Not found',
             'Content-Type': 'application/json'
         }), '{}')),
     ])
     with self.assertRaises(net.NotFoundError):
         net.request('http://localhost/_ah/api/blah')
Beispiel #4
0
def rpc(req):
    """Sends an asynchronous pRPC request.

  This API is low level. Most users should use Client class instead.

  Args:
    req (Request): a pRPC request.

  Returns the response message if the RPC status code is OK.
  Otherwise raises an Error.
  """

    # The protocol is documented in
    # https://godoc.org/go.chromium.org/luci/grpc/prpc#hdr-Protocol

    # Ensure timeout is set, such that we use same values for deadline
    # parameter in net.request_async and X-Prpc-Timeout value are same.
    # Default to 10s, which is the default used in net.request_async.
    timeout = req.timeout or 10

    headers = (req.metadata or {}).copy()
    headers['Content-Type'] = _BINARY_MEDIA_TYPE
    headers['Accept'] = _BINARY_MEDIA_TYPE
    headers['X-Prpc-Timeout'] = '%dS' % timeout

    try:
        res_bytes = net.request(
            url='http%s://%s/prpc/%s/%s' % (
                '' if req.insecure else 's',
                req.hostname,
                req.service_name,
                req.method_name,
            ),
            method='POST',
            payload=req.request_message.SerializeToString(),
            headers=headers,
            include_auth=req.include_auth,
            deadline=timeout,
            max_attempts=req.max_attempts or 4,
        )
        # Unfortunately, net module does not expose headers of HTTP 200
        # responses.
        # Assume (HTTP OK => pRPC OK).
    except net.Error as ex:
        # net.Error means HTTP status code was not 200.
        try:
            code = codes.INT_TO_CODE[int(ex.headers['X-Prpc-Grpc-Code'])]
        except (ValueError, KeyError, TypeError):
            raise ProtocolError(
                'response does not contain a valid X-Prpc-Grpc-Code header')
        msg = ex.response.decode('utf-8', 'ignore')
        raise RpcError(msg, code, ex.headers)

    # Status code is OK.
    # Parse the response and return it.
    res = req.response_message
    res.ParseFromString(res_bytes)
    return res
 def test_gives_up_retrying(self):
     self.mock_httplib2([
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({
             'status': 500,
             'reason': 'server error'
         }), 'server error')),
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({
             'status': 500,
             'reason': 'server error'
         }), 'server error')),
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({}), 'response body')),
     ])
     with self.assertRaises(net.Error):
         net.request('http://localhost/123', max_attempts=2)
 def test_crappy_cloud_endpoints_404_is_retried(self):
     self.mock_httplib2([
         ({
             'uri': 'http://localhost/_ah/api/blah'
         }, (httplib2.Response({
             'status': 404,
             'reason': 'Not found'
         }), 'Not found')),
         ({
             'uri': 'http://localhost/_ah/api/blah'
         }, (httplib2.Response({}), 'response body')),
     ])
     response = net.request('http://localhost/_ah/api/blah')
     self.assertEqual('response body', response)
 def test_retries_transient_errors(self):
     self.mock_httplib2([
         ({
             'uri': 'http://localhost/123'
         }, httplib2.HttpLib2Error()),
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({
             'status': 408,
             'reason': 'client timeout',
         }), 'client timeout')),
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({
             'status': 500,
             'reason': 'server error',
         }), 'server error')),
         ({
             'uri': 'http://localhost/123'
         }, (httplib2.Response({}), 'response body')),
     ])
     response = net.request('http://localhost/123', max_attempts=4)
     self.assertEqual('response body', response)
 def test_request_works(self):
     self.mock_httplib2([
         ({
             'headers': {
                 'Accept': 'text/plain',
                 'Authorization': 'Bearer token'
             },
             'method': 'POST',
             'body': 'post body',
             'uri': 'http://localhost/123?a=%3D&b=%26',
         }, (httplib2.Response({}), 'response body')),
     ])
     response = net.request(url='http://localhost/123',
                            method='POST',
                            payload='post body',
                            params={
                                'a': '=',
                                'b': '&'
                            },
                            headers={'Accept': 'text/plain'},
                            include_auth=True,
                            deadline=123,
                            max_attempts=5)
     self.assertEqual('response body', response)