Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListObjects doesn't decode UserMetadata correctly #2054

Open
Lumaraf opened this issue Jan 21, 2025 · 3 comments
Open

ListObjects doesn't decode UserMetadata correctly #2054

Lumaraf opened this issue Jan 21, 2025 · 3 comments

Comments

@Lumaraf
Copy link

Lumaraf commented Jan 21, 2025

When ListObjects is used with the WithMetadata: true option the returned UserMetadata is not decoded to what was set via PutObject and what GetObject and StatObject would return.

package main

import (
	"bytes"
	"context"
	"fmt"
	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
)

func main() {
	client, err := minio.New("127.0.0.1:9000", &minio.Options{
		Creds:  credentials.NewStaticV4("minio-user", "minio-password", ""),
		Secure: false,
	})
	if err != nil {
		panic(err)
	}

	bucket := "usermeta-test"

	client.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{})
	defer func() {
		client.RemoveBucket(context.Background(), bucket)
	}()

	content := []byte("hello world")

	_, err = client.PutObject(context.Background(), bucket, "hello.txt", bytes.NewReader(content), int64(len(content)), minio.PutObjectOptions{
		UserMetadata: map[string]string{
			"Hello": "World",
		},
	})
	if err != nil {
		panic(err)
	}

	info, err := client.StatObject(context.Background(), bucket, "hello.txt", minio.StatObjectOptions{})
	if err != nil {
		panic(err)
	}
	fmt.Println("StatObject >", info.Key, info.UserMetadata)

	objs := client.ListObjects(context.Background(), bucket, minio.ListObjectsOptions{
		WithMetadata: true,
	})
	for obj := range objs {
		fmt.Println("ListObjects >", obj.Key, obj.UserMetadata)
	}
}

Output:

StatObject > hello.txt map[Hello:World]
ListObjects > hello.txt map[X-Amz-Meta-Hello:World content-type:application/octet-stream expires:Mon, 01 Jan 0001 00:00:00 GMT]

For StatObject UserMetadata contains exactly the same entries that were saved via PutObject. The UserMetadata returned by ListObjects still has a X-Amz-Meta-prefix for the keys and an additional content-type and expires entries.

@klauspost
Copy link
Contributor

Not sure we can actually change that without breaking existing use of the function.

@harshavardhana
Copy link
Member

The input is taken in user-friendly form, and as x-and-meta-(tag) - list objects return the exact value present on the object. @klauspost we can return a UserFriendly form in a separate value.

But its not necessary since the library supports both x-amz-meta-tag and tag interchangeably.

@klauspost
Copy link
Contributor

Yeah. Would be nice for it to be symmetric, but we can expect code to rely on the full header key to be out there, so a separate field would be needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants