Skip to content

Content-Type header gets duplicated in multipart uploads when using MultipartUploadClient #3453

@louisnow

Description

@louisnow

Summary

When using MultipartUploadClient, if I create a multipart upload with contentType("audio/mp4"), upload some parts, and complete the upload - when I fetch the blob afterwards, the Content-Type comes back as "audio/mp4,audio/mp4" instead of just "audio/mp4".

I've been working on adding GCS SDK support to S3Proxy (tracking in gaul/s3proxy#76) and came across this bug.

Environment

  • google-cloud-storage: 2.61.0
  • Java: 17
  • Tested against real GCS

Steps to reproduce

HttpStorageOptions options = StorageOptions.http()
    .setProjectId("my-project")
    .setHost("https://storage.googleapis.com/")
    .build();

Storage storage = options.getService();
MultipartUploadClient mpuClient = MultipartUploadClient.create(
    MultipartUploadSettings.of(options));

// Start the upload with a Content-Type
CreateMultipartUploadRequest createRequest = CreateMultipartUploadRequest.builder()
    .bucket("my-bucket")
    .key("test-object")
    .contentType("audio/mp4")
    .build();

CreateMultipartUploadResponse createResponse = mpuClient.createMultipartUpload(createRequest);
String uploadId = createResponse.uploadId();

// Upload a part
byte[] data = "test data".getBytes(StandardCharsets.UTF_8);
UploadPartRequest partRequest = UploadPartRequest.builder()
    .bucket("my-bucket")
    .key("test-object")
    .uploadId(uploadId)
    .partNumber(1)
    .build();

UploadPartResponse partResponse = mpuClient.uploadPart(
    partRequest, RequestBody.of(ByteBuffer.wrap(data)));

// Complete it
CompleteMultipartUploadRequest completeRequest = CompleteMultipartUploadRequest.builder()
    .bucket("my-bucket")
    .key("test-object")
    .uploadId(uploadId)
    .multipartUpload(CompletedMultipartUpload.builder()
        .parts(List.of(CompletedPart.builder()
            .partNumber(1)
            .eTag(partResponse.eTag())
            .build()))
        .build())
    .build();

mpuClient.completeMultipartUpload(completeRequest);

// Now check what we got
Blob blob = storage.get("my-bucket", "test-object");
System.out.println(blob.getContentType());
// Prints: "audio/mp4,audio/mp4"
// Should be: "audio/mp4"

Other uploads work fine

This only seems to affect the XML API multipart uploads via MultipartUploadClient. Regular uploads with Storage.create() and compose operations with Storage.compose() both handle Content-Type correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api: storageIssues related to the googleapis/java-storage API.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions