put_account_meta, get_container_meta, put_container_meta, get_object_meta, put_object_meta,
validate_modification_preconditions, validate_matching_preconditions, copy_or_move_object,
get_content_length, get_range, get_content_range, raw_input_socket, socket_read_iterator,
- ObjectWrapper, api_method)
+ ObjectWrapper, hashmap_hash, api_method)
from pithos.backends import backend
raise ItemNotFound('Container does not exist')
# Update ETag.
- # TODO: Decide on the new ETag to use here.
+ # TODO: Move this to the backend.
meta = {}
- md5 = hashlib.md5()
- md5.update(str(hashmap))
- meta['hash'] = md5.hexdigest().lower()
+ meta['hash'] = hashmap_hash(hashmap)
try:
backend.update_object_meta(request.user, v_container, v_object, meta)
except NameError:
from time import time
from traceback import format_exc
from wsgiref.handlers import format_date_time
+from binascii import hexlify
from django.conf import settings
from django.http import HttpResponse
out.append('')
return '\r\n'.join(out)
+def hashmap_hash(hashmap):
+ """ Produce the root hash, treating the hashmap as a Merkle-like tree."""
+
+ def subhash(d):
+ h = hashlib.new(backend.hash_algorithm)
+ h.update(d)
+ return h.digest()
+
+ # TODO: Should create the whole tree and decide what to do with fillers.
+ h = hashmap
+ h = [subhash(h[x] + (h[x + 1] if x + 1 < len(h) else '')) for x in range(0, len(h), 2)]
+ while len(h) > 1:
+ h = [subhash(h[x] + (h[x + 1] if x + 1 < len(h) else '')) for x in range(0, len(h), 2)]
+ return hexlify(h[0])
+
def update_response_headers(request, response):
if request.serialization == 'xml':
response['Content-Type'] = 'application/xml; charset=UTF-8'