def request(self, url, method, **kwargs): raise_exc = kwargs.pop("raise_exc", True) resp = super(SessionClient, self).request(url, method, raise_exc=False, **kwargs) if raise_exc and resp.status_code >= 400: LOG.trace("Error communicating with {url}: {exc}".format(url=url, exc=exc.from_response(resp))) raise exc.from_response(resp) return resp, resp.text
def request(self, url, method, **kwargs): raise_exc = kwargs.pop('raise_exc', True) resp, body = super(SessionClient, self).request(url, method, raise_exc=False, **kwargs) if raise_exc and resp.status_code >= 400: LOG.warning(exc.from_response(resp)) raise exc.from_response(resp) return resp, body
def request(self, url, method, **kwargs): raise_exc = kwargs.pop('raise_exc', True) resp = super(SessionClient, self).request(url, method, raise_exc=False, **kwargs) if raise_exc and resp.status_code >= 400: LOG.trace("Error communicating with {url}: {exc}" .format(url=url, exc=exc.from_response(resp))) raise exc.from_response(resp) return resp, resp.text
def _http_request(self, url, method, **kwargs): """ Send an http request with the specified characteristics. Wrapper around httplib.HTTP(S)Connection.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) self.log_curl_request(method, url, kwargs) conn = self.get_connection() try: conn_params = self.connection_params[1][2] conn_url = os.path.normpath('%s/%s' % (conn_params, url)) conn.request(method, conn_url, **kwargs) resp = conn.getresponse() except socket.gaierror as e: message = "Error finding address for %(url)s: %(e)s" % locals() raise exceptions.InvalidEndpoint(message=message) except (socket.error, socket.timeout) as e: endpoint = self.endpoint message = "Error communicating with %(endpoint)s %(e)s" % locals() raise exceptions.CommunicationError(message=message) body_iter = ResponseBodyIterator(resp) # Read body into string if it isn't obviously image data if resp.getheader('content-type', None) != 'application/octet-stream': body_str = ''.join([chunk for chunk in body_iter]) self.log_http_response(resp, body_str) body_iter = StringIO.StringIO(body_str) else: self.log_http_response(resp) if 400 <= resp.status < 600: LOG.warn("Request returned failure status.") raise exceptions.from_response(resp) elif resp.status in (301, 302, 305): # Redirected. Reissue the request to the new location. return self._http_request(resp['location'], method, **kwargs) elif resp.status == 300: raise exceptions.from_response(resp) return resp, body_iter
def download(self, app_id): url = '/v1/catalog/packages/{0}/download'.format(app_id) response = self.api.request(url, 'GET', log=False) if response.status_code == 200: return response.content else: raise exceptions.from_response(response)
def download(self, app_id): url = '/v1/catalog/packages/{0}/download'.format(app_id) response, iterator = self.api.raw_request('GET', url) if response.status == 200: return ''.join(iterator) else: raise exceptions.from_response(response)
def get_supplier_logo(self, app_id): url = '/v1/catalog/packages/{0}/supplier_logo'.format(app_id) response = self.api.request(url, 'GET') if response.status_code == 200: return response.content else: raise exceptions.from_response(response)
def raw_request(self, method, url, **kwargs): # A non-json request; instead of calling # super.request, need to call the grandparent # adapter.request raise_exc = kwargs.pop("raise_exc", True) if "body" in kwargs: if "data" in kwargs: raise ValueError("Can't provide both 'data' and " "'body' to a request") LOG.warning("Use of 'body' is deprecated; use 'data' instead") kwargs["data"] = kwargs.pop("body") resp = keystone_adapter.Adapter.request(self, url, method, raise_exc=False, **kwargs) if raise_exc and resp.status_code >= 400: LOG.trace("Error communicating with {url}: {exc}".format(url=url, exc=exc.from_response(resp))) raise exc.from_response(resp) return resp
def create(self, data, files): data = {'data': json.dumps(data)} url = '{0}/v1/catalog/packages'.format(self.api.endpoint) headers = {'X-Auth-Token': self.api.auth_token} response = requests.post(url, data=data, files=files, headers=headers) if not response.ok: setattr(response, 'status', response.status_code) raise exceptions.from_response(response) return self.resource_class(self, json.loads(response.content))
def test_handles_html(self): """exc.from_response should not print HTML.""" mock_resp = mock.Mock() mock_resp.status_code = 403 mock_resp.text = HTML_MSG mock_resp.headers = {"content-type": "text/html"} err = exc.from_response(mock_resp) self.assertIsInstance(err, exc.HTTPForbidden) self.assertEqual("403 Forbidden: Access was denied to this resource.", err.details)
def get_ui(self, app_id, loader_cls=None): if loader_cls is None: loader_cls = yaml.Loader url = '/v1/catalog/packages/{0}/ui'.format(app_id) response, iterator = self.api.raw_request('GET', url) if response.status == 200: return yaml.load(''.join(iterator), loader_cls) else: raise exceptions.from_response(response)
def get_ui(self, app_id, loader_cls=None): if loader_cls is None: loader_cls = yaml.SafeLoader url = '/v1/catalog/packages/{0}/ui'.format(app_id) response = self.api.request(url, 'GET') if response.status_code == 200: return yaml.load(response.content, loader_cls) else: raise exceptions.from_response(response)
def create(self, data, files): response = self.api.request( '/v1/catalog/packages', 'POST', data={'__metadata__': jsonutils.dumps(data)}, files=files) if not response.ok: setattr(response, 'status', response.status_code) raise exceptions.from_response(response) body = jsonutils.loads(response.text) return self.resource_class(self, body)
def create(self, data, files): response = self.api.request( '/v1/catalog/packages', 'POST', data={'__metadata__': jsonutils.dumps(data)}, files=files ) if not response.ok: setattr(response, 'status', response.status_code) raise exceptions.from_response(response) body = jsonutils.loads(response.text) return self.resource_class(self, body)
def test_handles_html(self): """exc.from_response should not print HTML.""" mock_resp = mock.Mock() mock_resp.status_code = 403 mock_resp.text = HTML_MSG mock_resp.headers = { "content-type": "text/html" } err = exc.from_response(mock_resp) self.assertIsInstance(err, exc.HTTPForbidden) self.assertEqual("403 Forbidden: Access was denied to this resource.", err.details)
def raw_request(self, method, url, **kwargs): # A non-json request; instead of calling # super.request, need to call the grandparent # adapter.request raise_exc = kwargs.pop('raise_exc', True) if 'body' in kwargs: if 'data' in kwargs: raise ValueError("Can't provide both 'data' and " "'body' to a request") LOG.warning("Use of 'body' is deprecated; use 'data' instead") kwargs['data'] = kwargs.pop('body') resp = keystone_adapter.Adapter.request(self, url, method, raise_exc=False, **kwargs) if raise_exc and resp.status_code >= 400: LOG.trace("Error communicating with {url}: {exc}" .format(url=url, exc=exc.from_response(resp))) raise exc.from_response(resp) return resp
def test_handles_json(self): """exc.from_response should not print JSON.""" mock_resp = mock.Mock() mock_resp.status_code = 413 mock_resp.json.return_value = { "overLimit": { "code": 413, "message": "OverLimit Retry...", "details": "Error Details...", "retryAt": "2015-08-31T21:21:06Z" } } mock_resp.headers = {"content-type": "application/json"} err = exc.from_response(mock_resp) self.assertIsInstance(err, exc.HTTPOverLimit) self.assertEqual("OverLimit Retry...", err.details)
def test_handles_json(self): """exc.from_response should not print JSON.""" mock_resp = mock.Mock() mock_resp.status_code = 413 mock_resp.json.return_value = { "overLimit": { "code": 413, "message": "OverLimit Retry...", "details": "Error Details...", "retryAt": "2015-08-31T21:21:06Z" } } mock_resp.headers = { "content-type": "application/json" } err = exc.from_response(mock_resp) self.assertIsInstance(err, exc.HTTPOverLimit) self.assertEqual("OverLimit Retry...", err.details)
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) 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 if self.timeout is not None: kwargs['timeout'] = float(self.timeout) # Allow the option not to follow redirects follow_redirects = kwargs.pop('follow_redirects', True) # 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 try: resp = requests.request( method, self.endpoint_url + url, allow_redirects=allow_redirects, **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, requests.exceptions.ConnectionError) as e: endpoint = self.endpoint message = ("Error communicating with %(endpoint)s %(e)s" % {'endpoint': endpoint, 'e': e}) raise exc.CommunicationError(message=message) self.log_http_response(resp) if 'X-Auth-Key' not in kwargs['headers'] and \ (resp.status_code == 401 or (resp.status_code == 500 and "(HTTP 401)" in resp.content)): raise exc.HTTPUnauthorized("Authentication failed. Please try" " again.\n%s" % resp.content) 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, # unless caller specified follow_redirects=False if follow_redirects: location = resp.headers.get('location') path = self.strip_endpoint(location) resp = self._http_request(path, method, **kwargs) elif resp.status_code == 300: raise exc.from_response(resp) return resp
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) 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 if self.timeout is not None: kwargs["timeout"] = float(self.timeout) # Allow the option not to follow redirects follow_redirects = kwargs.pop("follow_redirects", True) # 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 try: resp = requests.request(method, self.endpoint_url + url, allow_redirects=allow_redirects, **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, requests.exceptions.ConnectionError) as e: endpoint = self.endpoint message = "Error communicating with %(endpoint)s %(e)s" % {"endpoint": endpoint, "e": e} raise exc.CommunicationError(message=message) self.log_http_response(resp) if "X-Auth-Key" not in kwargs["headers"] and ( resp.status_code == 401 or (resp.status_code == 500 and "(HTTP 401)" in resp.content) ): raise exc.HTTPUnauthorized("Authentication failed. Please try" " again.\n%s" % resp.content) 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, # unless caller specified follow_redirects=False if follow_redirects: location = resp.headers.get("location") path = self.strip_endpoint(location) resp = self._http_request(path, method, **kwargs) elif resp.status_code == 300: raise exc.from_response(resp) return resp
def _http_request(self, url, method, **kwargs): """Send an http request with the specified characteristics. Wrapper around httplib.HTTP(S)Connection.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) if self.identity_headers: for k, v in self.identity_headers.iteritems(): kwargs['headers'].setdefault(k, v) self.log_curl_request(method, url, kwargs) conn = self.get_connection() # Note(flaper87): Before letting headers / url fly, # they should be encoded otherwise httplib will # complain. If we decide to rely on python-request # this wont be necessary anymore. kwargs['headers'] = self.encode_headers(kwargs['headers']) try: if self.proxy_url: url = '{0}/{1}'.format(self.endpoint, url) elif self.endpoint_path: url = '{0}/{1}'.format(self.endpoint_path, url) conn_url = posixpath.normpath(url) # Note(flaper87): Ditto, headers / url # encoding to make httplib happy. conn_url = strutils.safe_encode(conn_url) if kwargs['headers'].get('Transfer-Encoding') == 'chunked': conn.putrequest(method, conn_url) for header, value in kwargs['headers'].items(): conn.putheader(header, value) conn.endheaders() chunk = kwargs['body'].read(CHUNKSIZE) # Chunk it, baby... while chunk: conn.send('%x\r\n%s\r\n' % (len(chunk), chunk)) chunk = kwargs['body'].read(CHUNKSIZE) conn.send('0\r\n\r\n') else: conn.request(method, conn_url, **kwargs) resp = conn.getresponse() except socket.gaierror as e: message = "Error finding address for %s: %s" % ( self.endpoint_hostname, e) raise exc.InvalidEndpoint(message=message) except (socket.error, socket.timeout) as e: endpoint = self.endpoint message = "Error communicating with %(endpoint)s %(e)s" % locals() raise exc.CommunicationError(message=message) body_iter = ResponseBodyIterator(resp) # Read body into string if it isn't obviously image data if resp.getheader('content-type', None) != 'application/octet-stream': body_str = ''.join([chunk for chunk in body_iter]) self.log_http_response(resp, body_str) body_iter = StringIO.StringIO(body_str) else: self.log_http_response(resp) if 400 <= resp.status < 600: LOG.error("Request returned failure status.") raise exc.from_response(resp, body_str) elif resp.status in (301, 302, 305): # Redirected. Reissue the request to the new location. return self._http_request(resp['location'], method, **kwargs) elif resp.status == 300: raise exc.from_response(resp) return resp, body_iter