Merge "Allow redirects to use location from response"

This commit is contained in:
Jenkins
2016-05-20 07:57:07 +00:00
committed by Gerrit Code Review
3 changed files with 16 additions and 33 deletions

View File

@@ -201,10 +201,14 @@ class HTTPClient(object):
# See issue: https://github.com/kennethreitz/requests/issues/1704
allow_redirects = False
# Use fully qualified URL from response header for redirects
if not parse.urlparse(url).netloc:
url = self.endpoint_url + url
try:
resp = requests.request(
method,
self.endpoint_url + url,
url,
allow_redirects=allow_redirects,
**kwargs)
except socket.gaierror as e:
@@ -231,23 +235,15 @@ class HTTPClient(object):
# unless caller specified redirect=False
if redirect:
location = resp.headers.get('location')
path = self.strip_endpoint(location)
resp = self._http_request(path, method, **kwargs)
if not location:
message = _("Location not returned with redirect")
raise exc.InvalidEndpoint(message=message)
resp = self._http_request(location, method, **kwargs)
elif resp.status_code == 300:
raise exc.from_response(resp)
return resp
def strip_endpoint(self, location):
if location is None:
message = _("Location not returned with 302")
raise exc.InvalidEndpoint(message=message)
elif location.lower().startswith(self.endpoint.lower()):
return location[len(self.endpoint):]
else:
message = _("Prohibited endpoint redirect %s") % location
raise exc.InvalidEndpoint(message=message)
def credentials_headers(self):
creds = {}
# NOTE(dhu): (shardy) When deferred_auth_method=password, Heat

View File

@@ -421,7 +421,7 @@ class HttpClientTest(testtools.TestCase):
{'location': 'http://example.com:8004/foo/bar'},
''))
mock_conn = http.requests.request(
'PUT', 'http://EXAMPLE.com:8004/foo/bar',
'PUT', 'http://example.com:8004/foo/bar',
allow_redirects=False,
headers={'Content-Type': 'application/json',
'Accept': 'application/json',
@@ -439,23 +439,6 @@ class HttpClientTest(testtools.TestCase):
self.assertEqual(200, resp.status_code)
def test_http_manual_redirect_prohibited(self):
mock_conn = http.requests.request(
'DELETE', 'http://example.com:8004/foo',
allow_redirects=False,
headers={'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': 'python-heatclient'})
mock_conn.AndReturn(
fakes.FakeHTTPResponse(
302, 'Found',
{'location': 'http://example.com:8004/'},
''))
self.m.ReplayAll()
client = http.HTTPClient('http://example.com:8004/foo')
self.assertRaises(exc.InvalidEndpoint,
client.json_request, 'DELETE', '')
def test_http_manual_redirect_error_without_location(self):
mock_conn = http.requests.request(
'DELETE', 'http://example.com:8004/foo',

View File

@@ -17,6 +17,8 @@ from heatclient.common import utils
import six
from six.moves.urllib import parse
from heatclient import exc
from heatclient.openstack.common._i18n import _
from heatclient.openstack.common.apiclient import base
@@ -106,8 +108,10 @@ class StackChildManager(base.BaseManager):
# redirected stacks:show, so pass redirect=False
resp = self.client.get('/stacks/%s' % stack_id, redirect=False)
location = resp.headers.get('location')
path = self.client.strip_endpoint(location)
return path[len('/stacks/'):]
if not location:
message = _("Location not returned with redirect")
raise exc.InvalidEndpoint(message=message)
return location.split('/stacks/', 1)[1]
class StackManager(StackChildManager):