From 41cdb942636b1fd1b91bf0898b57e6af6d3a688c Mon Sep 17 00:00:00 2001 From: Alistair Coles Date: Mon, 4 Dec 2017 16:16:10 -0800 Subject: [PATCH] Make 'directory' objects have zero-length etags in container listings 'Directory' objects are zero length so their etags can be forced to the hash of an empty string when pfs middleware constructs container listings. --- pfs_middleware/pfs_middleware/middleware.py | 17 +++++++++-------- pfs_middleware/tests/test_pfs_middleware.py | 8 ++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/pfs_middleware/pfs_middleware/middleware.py b/pfs_middleware/pfs_middleware/middleware.py index d51cb146b..838ab1f2c 100644 --- a/pfs_middleware/pfs_middleware/middleware.py +++ b/pfs_middleware/pfs_middleware/middleware.py @@ -417,7 +417,10 @@ def extract_container_metadata_from_headers(req): return meta_headers -def best_possible_etag(obj_metadata, account_name, ino, num_writes): +def best_possible_etag(obj_metadata, account_name, ino, num_writes, + is_dir=False): + if is_dir: + return EMPTY_OBJECT_ETAG if ORIGINAL_MD5_HEADER in obj_metadata: val = obj_metadata[ORIGINAL_MD5_HEADER] try: @@ -1159,7 +1162,7 @@ def _json_container_get_response(self, container_entries, account_name): ent["IsDir"]) etag = best_possible_etag( obj_metadata, account_name, - ent["InodeNumber"], ent["NumWrites"]) + ent["InodeNumber"], ent["NumWrites"], is_dir=ent["IsDir"]) json_entry = { "name": name, "bytes": size, @@ -1183,7 +1186,8 @@ def _xml_container_get_response(self, container_entries, account_name, etag = best_possible_etag( obj_metadata, account_name, container_entry["InodeNumber"], - container_entry["NumWrites"]) + container_entry["NumWrites"], + is_dir=container_entry["IsDir"]) container_node = ET.Element('object') name_node = ET.Element('name') @@ -1591,11 +1595,8 @@ def head_object(self, ctx): headers["Content-Type"] = guess_content_type(req.path, is_dir) headers["Content-Length"] = file_size - if is_dir: - headers["ETag"] = EMPTY_OBJECT_ETAG - else: - headers["ETag"] = best_possible_etag( - headers, ctx.account_name, ino, num_writes) + headers["ETag"] = best_possible_etag( + headers, ctx.account_name, ino, num_writes, is_dir=is_dir) headers["Last-Modified"] = last_modified_from_epoch_ns( last_modified_ns) headers["X-Timestamp"] = x_timestamp_from_epoch_ns( diff --git a/pfs_middleware/tests/test_pfs_middleware.py b/pfs_middleware/tests/test_pfs_middleware.py index bb897fd23..79004472c 100644 --- a/pfs_middleware/tests/test_pfs_middleware.py +++ b/pfs_middleware/tests/test_pfs_middleware.py @@ -1585,8 +1585,7 @@ def test_json(self): "name": "images", "bytes": 0, "content_type": "application/directory", - "hash": mware.construct_etag( - "AUTH_test", 2489682, 0), + "hash": "d41d8cd98f00b204e9800998ecf8427e", "last_modified": "2016-08-23T01:30:16.359210"}) self.assertEqual(resp_data[1], { "name": "images/avocado.png", @@ -1693,6 +1692,11 @@ def test_xml(self): self.assertEqual(name_node.tag, 'name') self.assertEqual(name_node.text, 'images') + hash_node = obj_attr_tags[1] + self.assertEqual(hash_node.tag, 'hash') + self.assertEqual(hash_node.text, "d41d8cd98f00b204e9800998ecf8427e") + self.assertEqual(hash_node.attrib, {}) + content_type_node = obj_attr_tags[3] self.assertEqual(content_type_node.tag, 'content_type') self.assertEqual(content_type_node.text, 'application/directory')