From 8ab6c8a22d7b8d5dfbf37e84e315c849bc36cd2b Mon Sep 17 00:00:00 2001 From: Jake Moshenko Date: Mon, 11 Jan 2016 16:43:20 -0500 Subject: [PATCH] Fix torrent hash generation to work in mixed stacks --- data/database.py | 4 ++-- data/fields.py | 7 +++++-- endpoints/v2/blob.py | 8 +++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/data/database.py b/data/database.py index 7d87610d9..0573eadea 100644 --- a/data/database.py +++ b/data/database.py @@ -809,8 +809,8 @@ class BlobUpload(BaseModel): chunk_count = IntegerField(default=0) uncompressed_byte_count = IntegerField(null=True) created = DateTimeField(default=datetime.now, index=True) - piece_sha_state = ResumableSHA1Field(null=True, default=resumablehashlib.sha1) - piece_hashes = Base64BinaryField(null=True, default='') + piece_sha_state = ResumableSHA1Field(null=True) + piece_hashes = Base64BinaryField(null=True) class Meta: database = db diff --git a/data/fields.py b/data/fields.py index c069c2d6d..f73bc0cf1 100644 --- a/data/fields.py +++ b/data/fields.py @@ -10,6 +10,9 @@ class _ResumableSHAField(TextField): raise NotImplementedError def db_value(self, value): + if value is None: + return None + sha_state = value.state() # One of the fields is a byte string, let's base64 encode it to make sure @@ -19,14 +22,14 @@ class _ResumableSHAField(TextField): return json.dumps(sha_state) def python_value(self, value): - to_resume = self._create_sha() if value is None: - return to_resume + return None sha_state = json.loads(value) # We need to base64 decode the data bytestring. sha_state[3] = base64.b64decode(sha_state[3]) + to_resume = self._create_sha() to_resume.set_state(sha_state) return to_resume diff --git a/endpoints/v2/blob.py b/endpoints/v2/blob.py index d8b1c9844..210e424f8 100644 --- a/endpoints/v2/blob.py +++ b/endpoints/v2/blob.py @@ -3,6 +3,8 @@ import re from flask import make_response, url_for, request, redirect, Response, abort as flask_abort +import resumablehashlib + from app import storage, app from auth.registry_jwt_auth import process_registry_jwt_auth from data import model, database @@ -224,9 +226,9 @@ def _upload_chunk(namespace, repo_name, upload_uuid): piece_hasher = None # TODO remove this when all in-progress blob uploads reliably contain piece hashes - if start_offset == 0 or found.piece_sha_state is not None: - piece_hasher = PieceHasher(app.config['TORRENT_PIECE_SIZE'], start_offset, found.piece_hashes, - found.piece_sha_state) + if start_offset == 0: + piece_hasher = PieceHasher(app.config['TORRENT_PIECE_SIZE'], start_offset, '', + resumablehashlib.sha1()) input_fp = wrap_with_handler(input_fp, piece_hasher.update) # If this is the first chunk and we're starting at the 0 offset, add a handler to gunzip the