From dddb6f3357f1b9bbe52759b3bd1f3056aafcb168 Mon Sep 17 00:00:00 2001 From: Kairat Kushaev Date: Tue, 18 Aug 2015 01:34:58 +0300 Subject: Catch InvalidURL when requesting store size If location URL looks like scp address: http://some_address:~/some_image then glance accepts this address and creates a malformed image. The problem here is because python http_client lib is trying to recognize '~' as port but it is not acceptable port name. The lib generates an InvalidURL exception but this exception is hidden in one of universal catchers(except Exception). We need to validate port name (is present before passing it to http_client lib. Change-Id: I36dddf7059711fb15ecb1fec4e438daf2bffcb60 Closes-bug: #1485792 (cherry picked from commit caf646af81118af114d38320b83146ff6ae95a07) --- glance_store/_drivers/http.py | 9 +++++++++ tests/unit/test_http_store.py | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/glance_store/_drivers/http.py b/glance_store/_drivers/http.py index a2073de..754ed71 100644 --- a/glance_store/_drivers/http.py +++ b/glance_store/_drivers/http.py @@ -89,6 +89,15 @@ class StoreLocation(glance_store.location.StoreLocation): if netloc == '': LOG.info(_("No address specified in HTTP URL")) raise exceptions.BadStoreUri(uri=uri) + else: + # IPv6 address has the following format [1223:0:0:..]: + # we need to be sure that we are validating port in both IPv4,IPv6 + delimiter = "]:" if netloc.count(":") > 1 else ":" + host, dlm, port = netloc.partition(delimiter) + # if port is present in location then validate port format + if port and not port.isdigit(): + raise exceptions.BadStoreUri(uri=uri) + self.netloc = netloc self.path = path diff --git a/tests/unit/test_http_store.py b/tests/unit/test_http_store.py index 5204f61..66fe23f 100644 --- a/tests/unit/test_http_store.py +++ b/tests/unit/test_http_store.py @@ -150,6 +150,27 @@ class TestHttpStore(base.StoreBaseTest, loc = location.get_location_from_uri(uri, conf=self.conf) self.assertRaises(exceptions.NotFound, self.store.get_size, loc) + def test_http_store_location_initialization(self): + """Test store location initialization from valid uris""" + uris = [ + "http://127.0.0.1:8000/ubuntu.iso", + "http://openstack.com:80/ubuntu.iso", + "http://[1080::8:800:200C:417A]:80/ubuntu.iso" + ] + for uri in uris: + location.get_location_from_uri(uri) + + def test_http_store_location_initialization_with_invalid_url(self): + """Test store location initialization from incorrect uris.""" + incorrect_uris = [ + "http://127.0.0.1:~/ubuntu.iso", + "http://openstack.com:some_text/ubuntu.iso", + "http://[1080::8:800:200C:417A]:some_text/ubuntu.iso" + ] + for uri in incorrect_uris: + self.assertRaises(exceptions.BadStoreUri, + location.get_location_from_uri, uri) + def test_http_get_raises_remote_service_unavailable(self): """Test http store raises RemoteServiceUnavailable.""" uri = "http://netloc/path/to/file.tar.gz" -- cgit v1.2.1