Revision 3a5994a8

b/snf-pithos-app/pithos/api/functions.py
66 66

  
67 67
from pithos.backends.base import (
68 68
    NotAllowedError, QuotaError, ContainerNotEmpty, ItemNotExists,
69
    VersionNotExists, ContainerExists)
69
    VersionNotExists, ContainerExists, InvalidHash)
70 70

  
71 71
from pithos.backends.filter import parse_filters
72 72

  
......
1115 1115
        raise faults.BadRequest('Invalid sharing header')
1116 1116
    except QuotaError, e:
1117 1117
        raise faults.RequestEntityTooLarge('Quota error: %s' % e)
1118
    except InvalidHash, e:
1119
        raise faults.BadRequest('Invalid hash: %s' % e)
1118 1120
    if not checksum and UPDATE_MD5:
1119 1121
        # Update the MD5 after the hashmap, as there may be missing hashes.
1120 1122
        checksum = hashmap_md5(request.backend, hashmap, size)
b/snf-pithos-app/pithos/api/test/objects.py
733 733
        self.assertEqual(r.status_code, 200)
734 734
        self.assertEqual(r.content, data)
735 735

  
736
    def test_create_object_by_invalid_hashmap(self):
737
        cname = self.container
738
        block_size = pithos_settings.BACKEND_BLOCK_SIZE
739

  
740
        # upload an object
741
        oname, data = self.upload_object(cname, length=block_size + 1)[:-1]
742
        # get it hashmap
743
        url = join_urls(self.pithos_path, self.user, cname, oname)
744
        r = self.get('%s?hashmap=&format=json' % url)
745
        data = r.content
746
        try:
747
            hashmap = json.loads(data)
748
        except:
749
            self.fail('JSON format expected')
750

  
751
        oname = get_random_name()
752
        url = join_urls(self.pithos_path, self.user, cname, oname)
753
        hashmap['hashes'] = [get_random_name()]
754
        r = self.put('%s?hashmap=' % url, data=json.dumps(hashmap))
755
        self.assertEqual(r.status_code, 400)
756

  
736 757

  
737 758
class ObjectPutCopy(PithosAPITest):
738 759
    def setUp(self):
b/snf-pithos-backend/pithos/backends/base.py
68 68
class VersionNotExists(IndexError):
69 69
    pass
70 70

  
71
class InvalidHash(TypeError):
72
    pass
71 73

  
72 74
class BaseBackend(object):
73 75
    """Abstract backend class.
b/snf-pithos-backend/pithos/backends/modular.py
48 48
from base import (DEFAULT_ACCOUNT_QUOTA, DEFAULT_CONTAINER_QUOTA,
49 49
                  DEFAULT_CONTAINER_VERSIONING, NotAllowedError, QuotaError,
50 50
                  BaseBackend, AccountExists, ContainerExists, AccountNotEmpty,
51
                  ContainerNotEmpty, ItemNotExists, VersionNotExists)
51
                  ContainerNotEmpty, ItemNotExists, VersionNotExists,
52
                  InvalidHash)
52 53

  
53 54

  
54 55
class DisabledAstakosClient(object):
......
930 931
        props = self._get_version(node, version)
931 932
        if props[self.HASH] is None:
932 933
            return 0, ()
933
        hashmap = self.store.map_get(binascii.unhexlify(props[self.HASH]))
934
        hashmap = self.store.map_get(self._unhexlify_hash(props[self.HASH]))
934 935
        return props[self.SIZE], [binascii.hexlify(x) for x in hashmap]
935 936

  
936 937
    def _update_object_hash(self, user, account, container, name, size, type,
......
1015 1016
        if size == 0:  # No such thing as an empty hashmap.
1016 1017
            hashmap = [self.put_block('')]
1017 1018
        map = HashMap(self.block_size, self.hash_algorithm)
1018
        map.extend([binascii.unhexlify(x) for x in hashmap])
1019
        map.extend([self._unhexlify_hash(x) for x in hashmap])
1019 1020
        missing = self.store.block_search(map)
1020 1021
        if missing:
1021 1022
            ie = IndexError()
......
1273 1274
        """Return a block's data."""
1274 1275

  
1275 1276
        logger.debug("get_block: %s", hash)
1276
        block = self.store.block_get(binascii.unhexlify(hash))
1277
        block = self.store.block_get(self._unhexlify_hash(hash))
1277 1278
        if not block:
1278 1279
            raise ItemNotExists('Block does not exist')
1279 1280
        return block
......
1290 1291
        logger.debug("update_block: %s %s %s", hash, len(data), offset)
1291 1292
        if offset == 0 and len(data) == self.block_size:
1292 1293
            return self.put_block(data)
1293
        h = self.store.block_update(binascii.unhexlify(hash), offset, data)
1294
        h = self.store.block_update(self._unhexlify_hash(hash), offset, data)
1294 1295
        return binascii.hexlify(h)
1295 1296

  
1296 1297
    # Path functions.
......
1730 1731
            return False
1731 1732
        else:
1732 1733
            return True
1734

  
1735
    def _unhexlify_hash(self, hash):
1736
        try:
1737
            return binascii.unhexlify(hash)
1738
        except TypeError:
1739
            raise InvalidHash(hash)

Also available in: Unified diff