From f47672d12acb90421f16fdf4fe07975befb64a6e Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Wed, 4 Nov 2009 09:24:53 -0800 Subject: [PATCH] add parser for immutable directory caps: DIR2-CHK, DIR2-LIT, DIR2-CHK-Verifier --- src/allmydata/test/test_uri.py | 61 ++++++++++++++++++++++++++++++++++ src/allmydata/uri.py | 51 ++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/src/allmydata/test/test_uri.py b/src/allmydata/test/test_uri.py index 6dd95a29..1ee39ff1 100644 --- a/src/allmydata/test/test_uri.py +++ b/src/allmydata/test/test_uri.py @@ -331,3 +331,64 @@ class NewDirnode(unittest.TestCase): self.failUnless(IVerifierURI.providedBy(v)) self.failUnlessEqual(v._filenode_uri, u1.get_verify_cap()._filenode_uri) + + def test_immutable(self): + readkey = "\x01" * 16 + uri_extension_hash = hashutil.uri_extension_hash("stuff") + needed_shares = 3 + total_shares = 10 + size = 1234 + + fnuri = uri.CHKFileURI(key=readkey, + uri_extension_hash=uri_extension_hash, + needed_shares=needed_shares, + total_shares=total_shares, + size=size) + fncap = fnuri.to_string() + self.failUnlessEqual(fncap, "URI:CHK:aeaqcaibaeaqcaibaeaqcaibae:nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa:3:10:1234") + u1 = uri.ImmutableDirectoryURI(fnuri) + self.failUnless(u1.is_readonly()) + self.failIf(u1.is_mutable()) + self.failUnless(IURI.providedBy(u1)) + self.failIf(IFileURI.providedBy(u1)) + self.failUnless(IDirnodeURI.providedBy(u1)) + self.failUnless("DirectoryURI" in str(u1)) + u1_filenode = u1.get_filenode_uri() + self.failIf(u1_filenode.is_mutable()) + self.failUnless(u1_filenode.is_readonly()) + self.failUnlessEqual(u1_filenode.to_string(), fncap) + self.failUnless(str(u1)) + + u2 = uri.from_string(u1.to_string()) + self.failUnlessEqual(u1.to_string(), u2.to_string()) + self.failUnless(u2.is_readonly()) + self.failIf(u2.is_mutable()) + self.failUnless(IURI.providedBy(u2)) + self.failIf(IFileURI.providedBy(u2)) + self.failUnless(IDirnodeURI.providedBy(u2)) + + u3 = u2.get_readonly() + self.failUnlessEqual(u3.to_string(), u2.to_string()) + self.failUnless(str(u3)) + + u2_verifier = u2.get_verify_cap() + self.failUnless(isinstance(u2_verifier, + uri.ImmutableDirectoryURIVerifier), u2_verifier) + self.failUnless(IVerifierURI.providedBy(u2_verifier)) + u2_verifier_fileuri = u2_verifier.get_filenode_uri() + self.failUnless(IVerifierURI.providedBy(u2_verifier_fileuri)) + self.failUnlessEqual(u2_verifier_fileuri.to_string(), + fnuri.get_verify_cap().to_string()) + self.failUnless(str(u2_verifier)) + + def test_literal(self): + u1 = uri.LiteralDirectoryURI("data") + self.failUnless(str(u1)) + u1s = u1.to_string() + self.failUnlessEqual(u1.to_string(), "URI:DIR2-LIT:mrqxiyi") + self.failUnless(u1.is_readonly()) + self.failIf(u1.is_mutable()) + self.failUnless(IURI.providedBy(u1)) + self.failIf(IFileURI.providedBy(u1)) + self.failUnless(IDirnodeURI.providedBy(u1)) + self.failUnlessEqual(u1.get_verify_cap(), None) diff --git a/src/allmydata/uri.py b/src/allmydata/uri.py index 0fba6164..44a3b963 100644 --- a/src/allmydata/uri.py +++ b/src/allmydata/uri.py @@ -48,6 +48,7 @@ class _BaseURI: class CHKFileURI(_BaseURI): implements(IURI, IImmutableFileURI) + BASE_STRING='URI:CHK:' STRING_RE=re.compile('^URI:CHK:'+BASE32STR_128bits+':'+ BASE32STR_256bits+':'+NUMBER+':'+NUMBER+':'+NUMBER+ '$') @@ -159,6 +160,7 @@ class CHKFileVerifierURI(_BaseURI): class LiteralFileURI(_BaseURI): implements(IURI, IImmutableFileURI) + BASE_STRING='URI:LIT:' STRING_RE=re.compile('^URI:LIT:'+base32.BASE32STR_anybytes+'$') HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'LIT'+SEP+base32.BASE32STR_anybytes+'$') @@ -422,6 +424,44 @@ class ReadonlyDirectoryURI(_DirectoryBaseURI): def get_readonly(self): return self +class _ImmutableDirectoryBaseURI(_DirectoryBaseURI): + def __init__(self, filenode_uri=None): + if filenode_uri: + assert isinstance(filenode_uri, self.INNER_URI_CLASS), filenode_uri + _DirectoryBaseURI.__init__(self, filenode_uri) + + def is_mutable(self): + return False + + def is_readonly(self): + return True + + def get_readonly(self): + return self + +class ImmutableDirectoryURI(_ImmutableDirectoryBaseURI): + BASE_STRING='URI:DIR2-CHK:' + BASE_STRING_RE=re.compile('^'+BASE_STRING) + BASE_HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'DIR2-CHK'+SEP) + INNER_URI_CLASS=CHKFileURI + def get_verify_cap(self): + vcap = self._filenode_uri.get_verify_cap() + return ImmutableDirectoryURIVerifier(vcap) + + +class LiteralDirectoryURI(_ImmutableDirectoryBaseURI): + BASE_STRING='URI:DIR2-LIT:' + BASE_STRING_RE=re.compile('^'+BASE_STRING) + BASE_HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'DIR2-LIT'+SEP) + INNER_URI_CLASS=LiteralFileURI + def __init__(self, data=None): + filenode_uri = LiteralFileURI(data) + _ImmutableDirectoryBaseURI.__init__(self, filenode_uri) + def get_verify_cap(self): + # LIT caps have no verifier, since they aren't distributed + return None + + class DirectoryURIVerifier(_DirectoryBaseURI): implements(IVerifierURI) @@ -438,6 +478,13 @@ class DirectoryURIVerifier(_DirectoryBaseURI): def get_filenode_uri(self): return self._filenode_uri +class ImmutableDirectoryURIVerifier(DirectoryURIVerifier): + implements(IVerifierURI) + BASE_STRING='URI:DIR2-CHK-Verifier:' + BASE_STRING_RE=re.compile('^'+BASE_STRING) + BASE_HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'DIR2-CHK-VERIFIER'+SEP) + INNER_URI_CLASS=CHKFileVerifierURI + class UnknownURI: def __init__(self, uri): self._uri = uri @@ -465,6 +512,10 @@ def from_string(s): return ReadonlyDirectoryURI.init_from_string(s) elif s.startswith('URI:DIR2-Verifier:'): return DirectoryURIVerifier.init_from_string(s) + elif s.startswith('URI:DIR2-CHK:'): + return ImmutableDirectoryURI.init_from_string(s) + elif s.startswith('URI:DIR2-LIT:'): + return LiteralDirectoryURI.init_from_string(s) return UnknownURI(s) def is_uri(s): -- 2.45.2