From ac26608e705861c536f8be2cc57aa0fc7e2f203d Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Tue, 4 Feb 2020 12:55:39 -0800 Subject: [PATCH] add support for loading via https urls... --- casimport/__init__.py | 62 ++++++++++++++++++++++++++++++-- fixtures/randpkg/cas_aliases.txt | 1 + 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/casimport/__init__.py b/casimport/__init__.py index 4b66817..9e7f4b4 100644 --- a/casimport/__init__.py +++ b/casimport/__init__.py @@ -105,6 +105,19 @@ def tempattrset(obj, key, value): else: delattr(obj, key) +class HTTPSCAS(object): + def fetch_data(self, url): + if url.scheme != 'https': + raise ValueError('cannot handle scheme %s' % + repr(url.scheme)) + + url = urllib.parse.urlunparse(url) + with urllib.request.urlopen(url) as req: + if req.status // 100 != 2: + raise RuntimeError('bad fetch') + + return req.read() + class IPFSCAS(object): gwhost = 'gateway.ipfs.io' gwhost = 'cloudflare-ipfs.com' @@ -117,6 +130,7 @@ class IPFSCAS(object): if url.scheme != 'ipfs': raise ValueError('cannot handle scheme %s' % repr(url.scheme)) + gwurl = self.make_url(url) with urllib.request.urlopen(gwurl) as req: @@ -334,6 +348,7 @@ def defaultinit(casf): casf.register(FileDirCAS(cachedir)) casf.register(IPFSCAS()) + casf.register(HTTPSCAS()) # The global version _casfinder = CASFinder() @@ -461,8 +476,11 @@ class Test(unittest.TestCase): # it can be imported from cas.v1_f_330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3 import hello - # and that the last loader is the IPFSCAS - self.assertIsInstance(f._loaders[-1], IPFSCAS) + # and that the second loader is the IPFSCAS + self.assertIsInstance(f._loaders[1], IPFSCAS) + + # and that the third loader is the HTTPSCAS + self.assertIsInstance(f._loaders[2], HTTPSCAS) with CASFinder() as f: defaultinit(f) @@ -484,9 +502,11 @@ class Test(unittest.TestCase): 'hello': [ 'hash://sha256/330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3?type=text/x-python', 'ipfs://bafkreibtbcckul7lwxqz7nyzj3dknhwrdxj5o4jc6gsroxxjhzz46albym', + 'https://www.funkthat.com/gitea/jmg/casimport/raw/commit/753e64f53c73d9d1afc4d8a617edb9d3542dcea2/fixtures/hello.py', ], 'hash://sha256/330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3': [ 'ipfs://bafkreibtbcckul7lwxqz7nyzj3dknhwrdxj5o4jc6gsroxxjhzz46albym', + 'https://www.funkthat.com/gitea/jmg/casimport/raw/commit/753e64f53c73d9d1afc4d8a617edb9d3542dcea2/fixtures/hello.py', ], }) @@ -592,6 +612,44 @@ class Test(unittest.TestCase): with self.assertRaises(RuntimeError): ipfs.fetch_data(hashurl) + # Note: mostly copied from above, test_ipfscasloader + @mock.patch('urllib.request.urlopen') + def test_httpscasloader(self, uomock): + # prep return test data + with open(self.fixtures / 'hello.py') as fp: + # that returns the correct data + httpsdata = fp.read() + + # that the https CAS loader + httpsldr = HTTPSCAS() + + # that the request is successfull + uomock.return_value.__enter__.return_value.status = 200 + + # and returns the correct data + uomock.return_value.__enter__.return_value.read.return_value = httpsdata + + # that when called + hashurl = urllib.parse.urlparse('https://www.funkthat.com/gitea/jmg/casimport/raw/commit/753e64f53c73d9d1afc4d8a617edb9d3542dcea2/fixtures/hello.py') + data = httpsldr.fetch_data(hashurl) + + # it opens the correct url + uomock.assert_called_with('https://www.funkthat.com/gitea/jmg/casimport/raw/commit/753e64f53c73d9d1afc4d8a617edb9d3542dcea2/fixtures/hello.py') + + # and returns the correct data + self.assertEqual(data, httpsdata) + + with self.assertRaises(ValueError): + # that a hash url fails + httpsldr.fetch_data(urllib.parse.urlparse('hash://sha256/asldfkj')) + + # that when the request fails + uomock.return_value.__enter__.return_value.status = 400 + + # it raises a RuntimeError + with self.assertRaises(RuntimeError): + httpsldr.fetch_data(hashurl) + def test_overlappingaliases(self): # make sure that an aliases file is consistent and does not # override other urls. That is that any hashes are diff --git a/fixtures/randpkg/cas_aliases.txt b/fixtures/randpkg/cas_aliases.txt index f5dd8e4..0b9f323 100644 --- a/fixtures/randpkg/cas_aliases.txt +++ b/fixtures/randpkg/cas_aliases.txt @@ -1,2 +1,3 @@ hello hash://sha256/330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3?type=text/x-python hello ipfs://bafkreibtbcckul7lwxqz7nyzj3dknhwrdxj5o4jc6gsroxxjhzz46albym +hello https://www.funkthat.com/gitea/jmg/casimport/raw/commit/753e64f53c73d9d1afc4d8a617edb9d3542dcea2/fixtures/hello.py