Skip to content

ListPartsArgs cannot specify the object key in MinIO Java SDK 9.0.3 #1714

Description

@itzlyg

Description

In MinIO Java SDK 9.0.3, ListPartsArgs.Builder does not provide a way to specify the object key required by the S3 ListParts operation.

ListPartsArgs extends ObjectArgs, but its Builder extends BucketArgs.Builder instead of ObjectArgs.Builder. As a result, ListPartsArgs.builder() does not expose the object(String) method.

This causes the generated ListParts request to omit the object key.

Version

  • MinIO Java SDK: 9.0.3

S3 ListParts request

According to the S3 API, the ListParts request uses the object key as the request path:

GET /Key?max-parts=MaxParts&part-number-marker=PartNumberMarker&uploadId=UploadId HTTP/1.1
Host: Bucket.s3.amazonaws.com

For a path-style S3 request, the equivalent request is:

GET /Bucket/Key?max-parts=MaxParts&part-number-marker=PartNumberMarker&uploadId=UploadId HTTP/1.1

The object key is therefore a required part of the request URI.

Current behavior

With MinIO Java SDK 9.0.3, it is not possible to specify the object key through ListPartsArgs.Builder because object(String) is not available.

For example, this cannot be written:

ListPartsArgs.builder()
    .bucket(bucket)
    .object(key)
    .uploadId(uploadId)
    .maxParts(1000)
    .build();

The actual request generated by the SDK is:

GET /large?max-parts=1000&uploadId=Njk3YjE3MD...

The object key is missing entirely.

The server then interprets the request as a bucket-level operation and returns ListBucketResult, for example:

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Name>large</Name>
    <Prefix></Prefix>
    <Marker></Marker>
    <MaxKeys>1000</MaxKeys>
    ...
</ListBucketResult>

instead of the expected ListPartsResult.

Relevant source code

ListPartsArgs extends ObjectArgs:

public class ListPartsArgs extends ObjectArgs {
    ...
}

However, its builder is declared as:

public static final class Builder
    extends BucketArgs.Builder<Builder, ListPartsArgs> {
    ...
}

This means the builder does not inherit the object(String) method provided by ObjectArgs.Builder.

The expected inheritance would be:

public static final class Builder
    extends ObjectArgs.Builder<Builder, ListPartsArgs> {

which would allow:

ListPartsArgs.builder()
    .bucket(bucket)
    .object(key)
    .uploadId(uploadId)
    .maxParts(1000)
    .build();

Expected behavior

ListPartsArgs should provide a way to specify the object key so that the generated request contains the key in the URI.

For example:

Bucket = large
Key = path/to/object.bin
UploadId = Njk3YjE3MD...
MaxParts = 1000

The generated path-style request should be equivalent to:

GET /large/path/to/object.bin?max-parts=1000&uploadId=Njk3YjE3MD...

with part-number-marker included when applicable.

The response should then be parsed as an S3 ListPartsResult.

Proposed fix

Change the ListPartsArgs.Builder inheritance from:

extends BucketArgs.Builder<Builder, ListPartsArgs>

to:

extends ObjectArgs.Builder<Builder, ListPartsArgs>

and add a regression test covering a multipart upload whose object key is non-empty.

The regression test should verify that:

  1. The object key can be specified through ListPartsArgs.Builder.
  2. The generated request URI contains the object key.
  3. max-parts, part-number-marker, and uploadId are correctly generated.
  4. The response is parsed as ListPartsResult rather than ListBucketResult.

Additional note

This is not a MinIO server compatibility issue. The generated request is missing a required component of the S3 ListParts request because the Java SDK does not expose the object key through ListPartsArgs.Builder.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions