diff --git a/b2sdk/raw_api.py b/b2sdk/raw_api.py index 19d4fabf7..08afaeb2c 100644 --- a/b2sdk/raw_api.py +++ b/b2sdk/raw_api.py @@ -830,6 +830,7 @@ def copy_part( _add_range_header(range_dict, bytes_range) kwargs['range'] = range_dict['Range'] if destination_server_side_encryption is not None: + assert destination_server_side_encryption.mode != EncryptionMode.SSE_B2 kwargs['destinationServerSideEncryption' ] = destination_server_side_encryption.as_value_dict() return self._post_json( @@ -1100,10 +1101,14 @@ def test_raw_api_helper(raw_api): io.BytesIO(part_contents) ) + # b2_copy_part + print('b2_copy_part') + raw_api.copy_part(api_url, account_auth_token, file_id, large_file_id, 2, (0, 5)) + # b2_list_parts print('b2_list_parts') parts_response = raw_api.list_parts(api_url, account_auth_token, large_file_id, 1, 100) - assert [1] == [part['partNumber'] for part in parts_response['parts']] + assert [1, 2] == [part['partNumber'] for part in parts_response['parts']] # b2_list_unfinished_large_files unfinished_list = raw_api.list_unfinished_large_files(api_url, account_auth_token, bucket_id) @@ -1111,14 +1116,13 @@ def test_raw_api_helper(raw_api): assert file_info == unfinished_list['files'][0]['fileInfo'] # b2_finish_large_file - # We don't upload enough data to actually finish on, so we'll just - # check that the right error is returned. print('b2_finish_large_file') try: raw_api.finish_large_file(api_url, account_auth_token, large_file_id, [part_sha1]) raise Exception('finish should have failed') except Exception as e: assert 'large files must have at least 2 parts' in str(e) + # TODO: make another attempt to finish but this time successfully # b2_update_bucket print('b2_update_bucket') diff --git a/b2sdk/raw_simulator.py b/b2sdk/raw_simulator.py index 44bb5fc5e..e57cccef0 100644 --- a/b2sdk/raw_simulator.py +++ b/b2sdk/raw_simulator.py @@ -1125,6 +1125,10 @@ def copy_part( bytes_range=None, destination_server_side_encryption: Optional[EncryptionSetting] = None, ): + if destination_server_side_encryption is not None and destination_server_side_encryption.mode == EncryptionMode.SSE_B2: + raise ValueError( + 'unsupported sse mode for copy_part!' + ) # SSE-B2 is only to be marked in b2_start_large_file src_bucket_id = self.file_id_to_bucket_id[source_file_id] src_bucket = self._get_bucket_by_id(src_bucket_id) dest_bucket_id = self.file_id_to_bucket_id[large_file_id] diff --git a/b2sdk/transfer/emerge/executor.py b/b2sdk/transfer/emerge/executor.py index 3f30f66d2..082552bca 100644 --- a/b2sdk/transfer/emerge/executor.py +++ b/b2sdk/transfer/emerge/executor.py @@ -395,7 +395,6 @@ def __init__( large_file_id, large_file_upload_state, finished_parts=None, - destination_encryption: Optional[EncryptionSetting] = None, ): super(LargeFileEmergeExecutionStepFactory, self).__init__(emerge_execution, emerge_part) self.part_number = part_number @@ -421,7 +420,7 @@ def create_upload_execution_step(self, stream_opener, stream_length=None, stream self.large_file_upload_state, stream_length=stream_length, stream_sha1=stream_sha1, - finished_parts=self.finished_parts + finished_parts=self.finished_parts, ) diff --git a/b2sdk/transfer/outbound/copy_manager.py b/b2sdk/transfer/outbound/copy_manager.py index a6fabed39..d1eb4f4e8 100644 --- a/b2sdk/transfer/outbound/copy_manager.py +++ b/b2sdk/transfer/outbound/copy_manager.py @@ -131,6 +131,10 @@ def _copy_part( EncryptionMode.SSE_B2, ) + # b2_copy_part doesn't need SSE-B2. Large file encryption is decided on b2_start_large_file. + if destination_encryption is not None and destination_encryption.mode == EncryptionMode.SSE_B2: + destination_encryption = None + # Check if this part was uploaded before if finished_parts is not None and part_number in finished_parts: # Report this part finished diff --git a/b2sdk/transfer/outbound/upload_manager.py b/b2sdk/transfer/outbound/upload_manager.py index 496bcb1d1..5e67e803c 100644 --- a/b2sdk/transfer/outbound/upload_manager.py +++ b/b2sdk/transfer/outbound/upload_manager.py @@ -137,6 +137,11 @@ def _upload_part( :param b2sdk.v1.EncryptionSetting encryption: encryption setting (``None`` if unknown) """ assert encryption is None or encryption.mode in (EncryptionMode.SSE_B2,) + + # b2_upload_part doesn't need SSE-B2. Large file encryption is decided on b2_start_large_file. + if encryption is not None and encryption.mode == EncryptionMode.SSE_B2: + encryption = None + # Check if this part was uploaded before if finished_parts is not None and part_number in finished_parts: # Report this part finished