From 584dc4ae946082a8beb64d7adbc3ff4f109ab3c7 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Fri, 8 Jun 2007 16:17:54 -0700 Subject: [PATCH] handle uri_extension with a non-bencode serialization scheme --- src/allmydata/download.py | 29 +++++++++++++++++++++++++++-- src/allmydata/encode.py | 13 +++++++++++-- src/allmydata/interfaces.py | 5 +++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/allmydata/download.py b/src/allmydata/download.py index 86c79689..498c171f 100644 --- a/src/allmydata/download.py +++ b/src/allmydata/download.py @@ -5,7 +5,7 @@ from twisted.python import log from twisted.internet import defer from twisted.application import service -from allmydata.util import idlib, mathutil, bencode, hashutil +from allmydata.util import idlib, mathutil, hashutil from allmydata.util.assertutil import _assert from allmydata import codec, hashtree from allmydata.Crypto.Cipher import AES @@ -341,6 +341,31 @@ class FileDownloader: # assert isinstance(vb, ValidatedBucket), \ # "vb is %s but should be a ValidatedBucket" % (vb,) + def _unpack_uri_extension_data(self, data): + d = {} + while data: + colon = data.index(":") + key = data[:colon] + data = data[colon+1:] + + colon = data.index(":") + number = data[:colon] + length = int(number) + data = data[colon+1:] + + value = data[:length] + assert data[length] == "," + data = data[length+1:] + + d[key] = value + + # convert certain things to numbers + for intkey in ("size", "segment_size", "num_segments", + "needed_shares", "total_shares"): + if intkey in d: + d[intkey] = int(d[intkey]) + return d + def _obtain_uri_extension(self, ignored): # all shareholders are supposed to have a copy of uri_extension, and # all are supposed to be identical. We compute the hash of the data @@ -353,7 +378,7 @@ class FileDownloader: msg = ("The copy of uri_extension we received from " "%s was bad" % bucket) raise BadURIExtensionHashValue(msg) - return bencode.bdecode(proposal) + return self._unpack_uri_extension_data(proposal) return self._obtain_validated_thing(None, self._uri_extension_sources, "uri_extension", diff --git a/src/allmydata/encode.py b/src/allmydata/encode.py index 997b5993..f062d14b 100644 --- a/src/allmydata/encode.py +++ b/src/allmydata/encode.py @@ -1,11 +1,12 @@ # -*- test-case-name: allmydata.test.test_encode -*- +import re from zope.interface import implements from twisted.internet import defer from twisted.python import log from allmydata.hashtree import HashTree from allmydata.Crypto.Cipher import AES -from allmydata.util import mathutil, bencode, hashutil +from allmydata.util import mathutil, hashutil from allmydata.util.assertutil import _assert from allmydata.codec import CRSEncoder from allmydata.interfaces import IEncoder @@ -432,7 +433,15 @@ class Encoder(object): def send_uri_extension_to_all_shareholders(self): log.msg("%s: sending uri_extension" % self) - uri_extension = bencode.bencode(self.uri_extension_data) + pieces = [] + for k in sorted(self.uri_extension_data.keys()): + value = self.uri_extension_data[k] + if isinstance(value, (int, long)): + value = "%d" % value + assert isinstance(value, str), k + assert re.match(r'^[a-zA-Z_\-]+$', k) + pieces.append(k + ":" + hashutil.netstring(value)) + uri_extension = "".join(pieces) self.uri_extension_hash = hashutil.uri_extension_hash(uri_extension) dl = [] for shareid in self.landlords.keys(): diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py index 3fc3bb3b..4f40fd21 100644 --- a/src/allmydata/interfaces.py +++ b/src/allmydata/interfaces.py @@ -69,6 +69,11 @@ class RIBucketWriter(RemoteInterface): mapping strings to other strings. The hash of this data is kept in the URI and verified before any of the data is used. All buckets for a given file contain identical copies of this data. + + The serialization format is specified with the following pseudocode: + for k in sorted(dict.keys()): + assert re.match(r'^[a-zA-Z_\-]+$', k) + write(k + ':' + netstring(dict[k])) """ return None -- 2.45.2