3 from allmydata.util import idlib, hashutil
6 assert uri.startswith("URI:")
7 if uri.startswith("URI:DIR:"):
9 if uri.startswith("URI:DIR-RO:"):
11 if uri.startswith("URI:LIT:"):
15 def is_filenode_uri(uri):
16 return get_uri_type(uri) in ("LIT", "CHK")
18 def get_filenode_size(uri):
19 assert is_filenode_uri(uri)
22 return len(unpack_lit(uri))
23 return unpack_uri(uri)['size']
26 # the URI shall be an ascii representation of the file. It shall contain
27 # enough information to retrieve and validate the contents. It shall be
28 # expressed in a limited character set (namely [TODO]).
30 def pack_uri(storage_index, key, uri_extension_hash,
31 needed_shares, total_shares, size):
32 # applications should pass keyword parameters into this
33 assert isinstance(storage_index, str)
34 assert len(storage_index) == 32 # sha256 hash
36 assert isinstance(uri_extension_hash, str)
37 assert len(uri_extension_hash) == 32 # sha56 hash
39 assert isinstance(key, str)
40 assert len(key) == 16 # AES-128
41 assert isinstance(needed_shares, int)
42 assert isinstance(total_shares, int)
43 assert isinstance(size, (int,long))
45 return "URI:%s:%s:%s:%d:%d:%d" % (idlib.b2a(storage_index), idlib.b2a(key),
46 idlib.b2a(uri_extension_hash),
47 needed_shares, total_shares, size)
51 assert uri.startswith("URI:"), uri
54 storage_index_s, key_s, uri_extension_hash_s,
55 needed_shares_s, total_shares_s, size_s) = uri.split(":")
56 assert header == "URI"
57 d['storage_index'] = idlib.a2b(storage_index_s)
58 d['key'] = idlib.a2b(key_s)
59 d['uri_extension_hash'] = idlib.a2b(uri_extension_hash_s)
60 d['needed_shares'] = int(needed_shares_s)
61 d['total_shares'] = int(total_shares_s)
62 d['size'] = int(size_s)
66 def pack_extension(data):
68 for k in sorted(data.keys()):
70 if isinstance(value, (int, long)):
72 assert isinstance(value, str), k
73 assert re.match(r'^[a-zA-Z_\-]+$', k)
74 pieces.append(k + ":" + hashutil.netstring(value))
75 uri_extension = "".join(pieces)
78 def unpack_extension(data):
81 colon = data.index(":")
85 colon = data.index(":")
91 assert data[length] == ","
92 data = data[length+1:]
96 # convert certain things to numbers
97 for intkey in ("size", "segment_size", "num_segments",
98 "needed_shares", "total_shares"):
100 d[intkey] = int(d[intkey])
104 def unpack_extension_readable(data):
105 unpacked = unpack_extension(data)
106 for k in sorted(unpacked.keys()):
108 unpacked[k] = idlib.b2a(unpacked[k])
112 return "URI:LIT:%s" % idlib.b2a(data)
115 assert uri.startswith("URI:LIT:")
116 data_s = uri[len("URI:LIT:"):]
117 return idlib.a2b(data_s)
120 def is_dirnode_uri(uri):
121 return uri.startswith("URI:DIR:") or uri.startswith("URI:DIR-RO:")
122 def is_mutable_dirnode_uri(uri):
123 return uri.startswith("URI:DIR:")
124 def unpack_dirnode_uri(uri):
125 assert is_dirnode_uri(uri)
127 # but note that the furl contains colons
128 for prefix in ("URI:DIR:", "URI:DIR-RO:"):
129 if uri.startswith(prefix):
130 uri = uri[len(prefix):]
134 colon = uri.rindex(":")
137 return furl, idlib.a2b(key)
139 def make_immutable_dirnode_uri(mutable_uri):
140 assert is_mutable_dirnode_uri(mutable_uri)
141 furl, writekey = unpack_dirnode_uri(mutable_uri)
142 readkey = hashutil.dir_read_key_hash(writekey)
143 return "URI:DIR-RO:%s:%s" % (furl, idlib.b2a(readkey))
145 def pack_dirnode_uri(furl, writekey):
146 return "URI:DIR:%s:%s" % (furl, idlib.b2a(writekey))