From a0715e966dbdeda18f6c80b2ebf1a8997e0fbb0f Mon Sep 17 00:00:00 2001 From: Yang Yu Date: Wed, 25 Sep 2013 10:39:36 -0500 Subject: [PATCH] Fix regression bug after removing posixpath in http.py After removing posixpath.normpath(url) in http.py, the code has a regression bug that the url like 'http://example.com:80/test' can not work. The code urlparse.urljoin() can not work as '%s%s' % (self.endpoint_path, url). Fixes bug #1230032 Change-Id: Ie7266fc3a067b92dfeed169086b4bf6a87dedbd6 --- glanceclient/common/http.py | 16 +++++++++++++++- tests/test_http.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/glanceclient/common/http.py b/glanceclient/common/http.py index 4cd66ec..852ea33 100644 --- a/glanceclient/common/http.py +++ b/glanceclient/common/http.py @@ -18,6 +18,7 @@ import errno import hashlib import httplib import logging +import posixpath import socket import StringIO import struct @@ -190,7 +191,20 @@ class HTTPClient(object): try: if self.endpoint_path: - url = urlparse.urljoin(self.endpoint_path, url) + # NOTE(yuyangbj): this method _http_request could either be + # called by API layer, or be called recursively with + # redirection. For example, url would be '/v1/images/detail' + # from API layer, but url would be 'https://example.com:92/ + # v1/images/detail' from recursion. + # See bug #1230032 and bug #1208618. + if url is not None: + all_parts = urlparse.urlparse(url) + if not (all_parts.scheme and all_parts.netloc): + norm_parse = posixpath.normpath + url = norm_parse('/'.join([self.endpoint_path, url])) + else: + url = self.endpoint_path + conn_url = urlparse.urlsplit(url).geturl() # Note(flaper87): Ditto, headers / url # encoding to make httplib happy. diff --git a/tests/test_http.py b/tests/test_http.py index f25227a..dc5cfb7 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -144,6 +144,34 @@ class TestClient(testtools.TestCase): resp, body = self.client.raw_request('GET', '/v1/images/detail') self.assertEqual(resp, fake) + def test_customized_path_raw_request(self): + """ + Verify the customized path being used for HTTP requests + reflects accurately + """ + + def check_request(method, path, **kwargs): + self.assertEqual(method, 'GET') + self.assertEqual(path, '/customized-path/v1/images/detail') + + # NOTE(yuyangbj): see bug 1230032 to get more info + endpoint = 'http://example.com:9292/customized-path' + client = http.HTTPClient(endpoint, token=u'abc123') + self.assertEqual(client.endpoint_path, '/customized-path') + + httplib.HTTPConnection.request( + mox.IgnoreArg(), + mox.IgnoreArg(), + headers=mox.IgnoreArg()).WithSideEffects(check_request) + + # fake the response returned by httplib + fake = utils.FakeResponse({}, StringIO.StringIO('Ok')) + httplib.HTTPConnection.getresponse().AndReturn(fake) + self.mock.ReplayAll() + + resp, body = client.raw_request('GET', '/v1/images/detail') + self.assertEqual(resp, fake) + def test_connection_refused_raw_request(self): """ Should receive a CommunicationError if connection refused.