|
@@ -105,6 +105,19 @@ def tempattrset(obj, key, value): |
|
|
else: |
|
|
else: |
|
|
delattr(obj, key) |
|
|
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): |
|
|
class IPFSCAS(object): |
|
|
gwhost = 'gateway.ipfs.io' |
|
|
gwhost = 'gateway.ipfs.io' |
|
|
gwhost = 'cloudflare-ipfs.com' |
|
|
gwhost = 'cloudflare-ipfs.com' |
|
@@ -117,6 +130,7 @@ class IPFSCAS(object): |
|
|
if url.scheme != 'ipfs': |
|
|
if url.scheme != 'ipfs': |
|
|
raise ValueError('cannot handle scheme %s' % |
|
|
raise ValueError('cannot handle scheme %s' % |
|
|
repr(url.scheme)) |
|
|
repr(url.scheme)) |
|
|
|
|
|
|
|
|
gwurl = self.make_url(url) |
|
|
gwurl = self.make_url(url) |
|
|
|
|
|
|
|
|
with urllib.request.urlopen(gwurl) as req: |
|
|
with urllib.request.urlopen(gwurl) as req: |
|
@@ -334,6 +348,7 @@ def defaultinit(casf): |
|
|
|
|
|
|
|
|
casf.register(FileDirCAS(cachedir)) |
|
|
casf.register(FileDirCAS(cachedir)) |
|
|
casf.register(IPFSCAS()) |
|
|
casf.register(IPFSCAS()) |
|
|
|
|
|
casf.register(HTTPSCAS()) |
|
|
|
|
|
|
|
|
# The global version |
|
|
# The global version |
|
|
_casfinder = CASFinder() |
|
|
_casfinder = CASFinder() |
|
@@ -461,8 +476,11 @@ class Test(unittest.TestCase): |
|
|
# it can be imported |
|
|
# it can be imported |
|
|
from cas.v1_f_330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3 import hello |
|
|
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: |
|
|
with CASFinder() as f: |
|
|
defaultinit(f) |
|
|
defaultinit(f) |
|
@@ -484,9 +502,11 @@ class Test(unittest.TestCase): |
|
|
'hello': [ |
|
|
'hello': [ |
|
|
'hash://sha256/330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3?type=text/x-python', |
|
|
'hash://sha256/330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3?type=text/x-python', |
|
|
'ipfs://bafkreibtbcckul7lwxqz7nyzj3dknhwrdxj5o4jc6gsroxxjhzz46albym', |
|
|
'ipfs://bafkreibtbcckul7lwxqz7nyzj3dknhwrdxj5o4jc6gsroxxjhzz46albym', |
|
|
|
|
|
'https://www.funkthat.com/gitea/jmg/casimport/raw/commit/753e64f53c73d9d1afc4d8a617edb9d3542dcea2/fixtures/hello.py', |
|
|
], |
|
|
], |
|
|
'hash://sha256/330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3': [ |
|
|
'hash://sha256/330884aa2febb5e19fb7194ec6a69ed11dd3d77122f1a5175ee93e73cf0161c3': [ |
|
|
'ipfs://bafkreibtbcckul7lwxqz7nyzj3dknhwrdxj5o4jc6gsroxxjhzz46albym', |
|
|
'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): |
|
|
with self.assertRaises(RuntimeError): |
|
|
ipfs.fetch_data(hashurl) |
|
|
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): |
|
|
def test_overlappingaliases(self): |
|
|
# make sure that an aliases file is consistent and does not |
|
|
# make sure that an aliases file is consistent and does not |
|
|
# override other urls. That is that any hashes are |
|
|
# override other urls. That is that any hashes are |
|
|