commit 133e3fcfb2c5a668998aaed18f6a31677427ab06
Author: Sofia Papagiannaki <spapagian@grnet.gr>
Date:   Wed Jul 3 18:37:09 2013 +0300

    pithos: return always etag
    
    Refs: #3554
    
    If update md5 is deactivated Pithos does not return an etag header.
    Pithos in that case should return the merkle hash as etag

diff --git a/snf-pithos-app/pithos/api/util.py b/snf-pithos-app/pithos/api/util.py
index 4a834eb..fb5b0bd 100644
--- a/snf-pithos-app/pithos/api/util.py
+++ b/snf-pithos-app/pithos/api/util.py
@@ -62,9 +62,8 @@ from pithos.api.settings import (BACKEND_DB_MODULE, BACKEND_DB_CONNECTION,
                                  BACKEND_BLOCK_SIZE, BACKEND_HASH_ALGORITHM,
                                  RADOS_STORAGE, RADOS_POOL_BLOCKS,
                                  RADOS_POOL_MAPS, TRANSLATE_UUIDS,
-                                 PUBLIC_URL_SECURITY,
-                                 PUBLIC_URL_ALPHABET,
-                                 COOKIE_NAME, BASE_HOST)
+                                 PUBLIC_URL_SECURITY, PUBLIC_URL_ALPHABET,
+                                 COOKIE_NAME, BASE_HOST, UPDATE_MD5)
 from pithos.api.resources import resources
 from pithos.backends.base import (NotAllowedError, QuotaError, ItemNotExists,
                                   VersionNotExists)
@@ -216,7 +215,7 @@ def get_object_headers(request):
 
 
 def put_object_headers(response, meta, restricted=False, token=None):
-    response['ETag'] = meta['checksum']
+    response['ETag'] = meta['hash'] if not UPDATE_MD5 else meta['checksum']
     response['Content-Length'] = meta['bytes']
     response.override_serialization = True
     response['Content-Type'] = meta.get('type', 'application/octet-stream')
@@ -260,11 +259,11 @@ def update_manifest_meta(request, v_account, meta):
                 request.user_uniq, v_account,
                 src_container, prefix=src_name, virtual=False)
             for x in objects:
-                src_meta = request.backend.get_object_meta(request.user_uniq,
-                                                           v_account,
-                                                           src_container,
-                                                           x[0], 'pithos', x[1])
-                etag += src_meta['checksum']
+                src_meta = request.backend.get_object_meta(
+                    request.user_uniq, v_account, src_container, x[0],
+                    'pithos', x[1])
+                etag += (src_meta['hash'] if not UPDATE_MD5 else
+                         src_meta['checksum'])
                 bytes += src_meta['bytes']
         except:
             # Ignore errors.
@@ -424,7 +423,7 @@ def validate_modification_preconditions(request, meta):
 def validate_matching_preconditions(request, meta):
     """Check that the ETag conforms with the preconditions set."""
 
-    etag = meta['checksum']
+    etag = meta['hash'] if not UPDATE_MD5 else meta['checksum']
     if not etag:
         etag = None
 
@@ -773,12 +772,12 @@ class SaveToBackendHandler(FileUploadHandler):
         if len(self.data) >= length:
             block = self.data[:length]
             self.file.hashmap.append(self.backend.put_block(block))
-            self.md5.update(block)
+            self.checksum_compute.update(block)
             self.data = self.data[length:]
 
     def new_file(self, field_name, file_name, content_type,
                  content_length, charset=None):
-        self.md5 = hashlib.md5()
+        self.checksum_compute = NoChecksum() if not UPDATE_MD5 else Checksum()
         self.data = ''
         self.file = UploadedFile(
             name=file_name, content_type=content_type, charset=charset)
@@ -795,7 +794,7 @@ class SaveToBackendHandler(FileUploadHandler):
         l = len(self.data)
         if l > 0:
             self.put_data(l)
-        self.file.etag = self.md5.hexdigest().lower()
+        self.file.etag = self.checksum_compute.hexdigest()
         return self.file
 
 
@@ -1161,3 +1160,21 @@ def view_method():
                 raise Exception(response)
         return wrapper
     return decorator
+
+
+class Checksum:
+    def __init__(self):
+        self.md5 = hashlib.md5()
+
+    def update(self, data):
+        self.md5.update(data)
+
+    def hexdigest(self):
+        return self.md5.hexdigest().lower()
+
+class NoChecksum:
+    def update(self, data):
+        pass
+
+    def hexdigest(self):
+        return ''
