Exemplo n.º 1
0
 def _check_status_code(self, resp, method, **kwargs):
     if self._unauthorized(resp):
         message = "Unauthorized error"
         raise exc.HTTPUnauthorized(message=message)
     elif 400 <= resp.status_code < 600:
         raise exc.from_response(resp)
     elif resp.status_code in (301, 302, 305):
         # Redirected. Reissue the request to the new location.
         location = resp.headers.get('location')
         if location is None:
             message = "Location not returned with 302"
             raise exc.InvalidEndpoint(message=message)
         elif location.startswith(self.endpoint):
             # shave off the endpoint, it will be prepended when we recurse
             location = location[len(self.endpoint):]
         else:
             message = "Prohibited endpoint redirect %s" % location
             raise exc.InvalidEndpoint(message=message)
         return self._http_request(location, method, **kwargs)
     elif resp.status_code == 300:
         raise exc.from_response(resp)
Exemplo n.º 2
0
 def _make_request(self, method, url, allow_redirects, timeout, **kwargs):
     try:
         resp = requests.request(method,
                                 self.endpoint_url + url,
                                 allow_redirects=allow_redirects,
                                 timeout=timeout,
                                 **kwargs)
     except socket.gaierror as e:
         message = ("Error finding address for %(url)s: %(e)s" % {
             'url': self.endpoint_url + url,
             'e': e
         })
         raise exc.InvalidEndpoint(message=message)
     except (socket.error, socket.timeout) as e:
         endpoint = self.endpoint
         message = ("Error communicating with %(endpoint)s %(e)s" % {
             'endpoint': endpoint,
             'e': e
         })
         raise exc.CommunicationError(message=message)
     except requests.Timeout as e:
         endpoint = self.endpoint
         message = (
             "Error %(method)s timeout request to %(endpoint)s %(e)s" % {
                 'method': method,
                 'endpoint': endpoint,
                 'e': e
             })
         raise exc.RequestTimeoutError(message=message)
     except requests.ConnectionError as ex:
         endpoint = self.endpoint
         message = ("Failed to connect to %s, error was %s" %
                    (endpoint, ex.message))
         raise exc.CommunicationError(message=message)
     self.log_http_response(resp)
     return resp
Exemplo n.º 3
0
    def _http_request(self, url, method, **kwargs):
        """Send an http request with the specified characteristics.

        Wrapper around requests.request to handle tasks such as
        setting headers and error handling.
        """
        # Copy the kwargs so we can reuse the original in case of redirects
        kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {}))
        kwargs['headers'].setdefault('User-Agent', USER_AGENT)
        if self.auth_token:
            kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
        else:
            kwargs['headers'].update(self.credentials_headers())
        if self.auth_url:
            kwargs['headers'].setdefault('X-Auth-Url', self.auth_url)
        if self.region_name:
            kwargs['headers'].setdefault('X-Region-Name', self.region_name)
        if self.include_pass and 'X-Auth-Key' not in kwargs['headers']:
            kwargs['headers'].update(self.credentials_headers())

        self.log_curl_request(method, url, kwargs)

        if self.cert_file and self.key_file:
            kwargs['cert'] = (self.cert_file, self.key_file)

        if self.verify_cert is not None:
            kwargs['verify'] = self.verify_cert

        # Since requests does not follow the RFC when doing redirection to sent
        # back the same method on a redirect we are simply bypassing it.  For
        # example if we do a DELETE/POST/PUT on a URL and we get a 302 RFC says
        # that we should follow that URL with the same method as before,
        # requests doesn't follow that and send a GET instead for the method.
        # Hopefully this could be fixed as they say in a comment in a future
        # point version i.e: 3.x
        # See issue: https://github.com/kennethreitz/requests/issues/1704
        allow_redirects = False
        timeout = None
        if method in ['POST', 'DELETE', 'PUT', 'PATCH']:
            timeout = self.write_timeout
        elif method is 'GET':
            timeout = self.read_timeout

        try:
            resp = requests.request(method,
                                    self.endpoint_url + url,
                                    allow_redirects=allow_redirects,
                                    timeout=timeout,
                                    **kwargs)
        except socket.gaierror as e:
            message = ("Error finding address for %(url)s: %(e)s" % {
                'url': self.endpoint_url + url,
                'e': e
            })
            raise exc.InvalidEndpoint(message=message)
        except (socket.error, socket.timeout) as e:
            endpoint = self.endpoint
            message = ("Error communicating with %(endpoint)s %(e)s" % {
                'endpoint': endpoint,
                'e': e
            })
            raise exc.CommunicationError(message=message)
        except requests.Timeout as e:
            endpoint = self.endpoint
            message = (
                "Error %(method)s timeout request to %(endpoint)s %(e)s" % {
                    'method': method,
                    'endpoint': endpoint,
                    'e': e
                })
            raise exc.RequestTimeoutError(message=message)

        self.log_http_response(resp)

        if (resp.status_code == 401
                or (resp.status_code == 500 and "(HTTP 401)" in resp.content)):
            # re-authenticate and attempt one more request
            try:
                self.re_authenticate()
                kwargs['headers']['X-Auth-Token'] = self.auth_token
                resp = requests.request(method,
                                        self.endpoint_url + url,
                                        allow_redirects=allow_redirects,
                                        timeout=timeout,
                                        **kwargs)
            except Exception as e:
                raise exc.HTTPUnauthorized(e)

        elif 400 <= resp.status_code < 600:
            raise exc.from_response(resp)
        elif resp.status_code in (301, 302, 305):
            # Redirected. Reissue the request to the new location.
            location = resp.headers.get('location')
            if location is None:
                message = "Location not returned with 302"
                raise exc.InvalidEndpoint(message=message)
            elif location.startswith(self.endpoint):
                # shave off the endpoint, it will be prepended when we recurse
                location = location[len(self.endpoint):]
            else:
                message = "Prohibited endpoint redirect %s" % location
                raise exc.InvalidEndpoint(message=message)
            return self._http_request(location, method, **kwargs)
        elif resp.status_code == 300:
            raise exc.from_response(resp)

        return resp