s3

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package s3 provides S3 client initialization and presigned URL generation for hold services. It supports S3, Storj, and Minio storage backends.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BlobPath

func BlobPath(digest string) string

BlobPath converts a digest (e.g., "sha256:abc123...") or temp path to a storage path Distribution stores blobs as: /docker/registry/v2/blobs/{algorithm}/{xx}/{hash}/data where xx is the first 2 characters of the hash for directory sharding NOTE: Path must start with / for filesystem driver This is used for OCI container layers (content-addressed, globally deduplicated)

Types

type AbortCall

type AbortCall struct {
	Bucket   string
	Key      string
	UploadID string
}

AbortCall records an AbortMultipartUpload call

type CompleteCall

type CompleteCall struct {
	Bucket   string
	Key      string
	UploadID string
	Parts    int
}

CompleteCall records a CompleteMultipartUpload call

type CreateMultipartCall

type CreateMultipartCall struct {
	Bucket string
	Key    string
}

CreateMultipartCall records a CreateMultipartUpload call

type GetObjectCall

type GetObjectCall struct {
	Bucket string
	Key    string
}

GetObjectCall records a PresignGetObject call

type HeadObjectCall

type HeadObjectCall struct {
	Bucket string
	Key    string
}

HeadObjectCall records a PresignHeadObject call

type MockS3Client

type MockS3Client struct {
	// TestServerURL is the base URL for generating fake presigned URLs.
	// Requests to these URLs should be handled by a test server (httptest.Server).
	TestServerURL string

	// UploadID is returned by CreateMultipartUpload.
	// If empty, a UUID is generated.
	UploadID string

	// Objects stores in-memory blobs for PutObject/HeadObject/DeleteObject/CopyObject/ListObjectsV2.
	Objects map[string][]byte

	CreateMultipartCalls []CreateMultipartCall
	CompleteCalls        []CompleteCall
	AbortCalls           []AbortCall
	UploadPartCalls      []UploadPartCall
	GetObjectCalls       []GetObjectCall
	HeadObjectCalls      []HeadObjectCall
	PutObjectCalls       []PutObjectCall

	// Error injection for testing error handling
	CreateMultipartError error
	CompleteError        error
	AbortError           error
	HeadObjectError      error
	CopyObjectError      error
	// contains filtered or unexported fields
}

MockS3Client implements S3Client for testing without real S3 credentials. It generates fake presigned URLs that point to a test server.

func NewMockS3Client

func NewMockS3Client(testServerURL string) *MockS3Client

NewMockS3Client creates a new mock S3 client for testing

func (*MockS3Client) AbortMultipartUpload

func (m *MockS3Client) AbortMultipartUpload(ctx context.Context, input *awss3.AbortMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.AbortMultipartUploadOutput, error)

AbortMultipartUpload implements S3Client

func (*MockS3Client) CompleteMultipartUpload

func (m *MockS3Client) CompleteMultipartUpload(ctx context.Context, input *awss3.CompleteMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.CompleteMultipartUploadOutput, error)

CompleteMultipartUpload implements S3Client

func (*MockS3Client) CopyObject

func (m *MockS3Client) CopyObject(ctx context.Context, input *awss3.CopyObjectInput, opts ...func(*awss3.Options)) (*awss3.CopyObjectOutput, error)

CopyObject implements S3Client

func (*MockS3Client) CreateMultipartUpload

func (m *MockS3Client) CreateMultipartUpload(ctx context.Context, input *awss3.CreateMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.CreateMultipartUploadOutput, error)

CreateMultipartUpload implements S3Client

func (*MockS3Client) DeleteObject

func (m *MockS3Client) DeleteObject(ctx context.Context, input *awss3.DeleteObjectInput, opts ...func(*awss3.Options)) (*awss3.DeleteObjectOutput, error)

DeleteObject implements S3Client

func (*MockS3Client) GetObject

func (m *MockS3Client) GetObject(ctx context.Context, input *awss3.GetObjectInput, opts ...func(*awss3.Options)) (*awss3.GetObjectOutput, error)

GetObject implements S3Client

func (*MockS3Client) GetObjectBytes

func (m *MockS3Client) GetObjectBytes(key string) []byte

GetObjectBytes is a test helper to read an object from the mock store (nil if not found).

func (*MockS3Client) HeadObject

func (m *MockS3Client) HeadObject(ctx context.Context, input *awss3.HeadObjectInput, opts ...func(*awss3.Options)) (*awss3.HeadObjectOutput, error)

HeadObject implements S3Client

func (*MockS3Client) ListObjectsV2

func (m *MockS3Client) ListObjectsV2(ctx context.Context, input *awss3.ListObjectsV2Input, opts ...func(*awss3.Options)) (*awss3.ListObjectsV2Output, error)

ListObjectsV2 implements S3Client

func (*MockS3Client) PresignGetObject

func (m *MockS3Client) PresignGetObject(ctx context.Context, input *awss3.GetObjectInput, expires time.Duration) (string, error)

PresignGetObject implements S3Client

func (*MockS3Client) PresignHeadObject

func (m *MockS3Client) PresignHeadObject(ctx context.Context, input *awss3.HeadObjectInput, expires time.Duration) (string, error)

PresignHeadObject implements S3Client

func (*MockS3Client) PresignPutObject

func (m *MockS3Client) PresignPutObject(ctx context.Context, input *awss3.PutObjectInput, expires time.Duration) (string, error)

PresignPutObject implements S3Client

func (*MockS3Client) PresignUploadPart

func (m *MockS3Client) PresignUploadPart(ctx context.Context, input *awss3.UploadPartInput, expires time.Duration) (string, error)

PresignUploadPart implements S3Client Returns a mock presigned URL for test server

func (*MockS3Client) PutObject

func (m *MockS3Client) PutObject(ctx context.Context, input *awss3.PutObjectInput, opts ...func(*awss3.Options)) (*awss3.PutObjectOutput, error)

PutObject implements S3Client

func (*MockS3Client) SetObject

func (m *MockS3Client) SetObject(key string, data []byte)

SetObject is a test helper to pre-populate an object in the mock store.

type PutObjectCall

type PutObjectCall struct {
	Bucket string
	Key    string
}

PutObjectCall records a PresignPutObject call

type RealS3Client

type RealS3Client struct {
	// contains filtered or unexported fields
}

RealS3Client wraps AWS SDK v2 *s3.Client to implement S3Client interface

func NewRealS3Client

func NewRealS3Client(client *awss3.Client) *RealS3Client

NewRealS3Client creates a new RealS3Client wrapper

func (*RealS3Client) AbortMultipartUpload

func (r *RealS3Client) AbortMultipartUpload(ctx context.Context, input *awss3.AbortMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.AbortMultipartUploadOutput, error)

AbortMultipartUpload implements S3Client

func (*RealS3Client) CompleteMultipartUpload

func (r *RealS3Client) CompleteMultipartUpload(ctx context.Context, input *awss3.CompleteMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.CompleteMultipartUploadOutput, error)

CompleteMultipartUpload implements S3Client

func (*RealS3Client) CopyObject

func (r *RealS3Client) CopyObject(ctx context.Context, input *awss3.CopyObjectInput, opts ...func(*awss3.Options)) (*awss3.CopyObjectOutput, error)

CopyObject implements S3Client

func (*RealS3Client) CreateMultipartUpload

func (r *RealS3Client) CreateMultipartUpload(ctx context.Context, input *awss3.CreateMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.CreateMultipartUploadOutput, error)

CreateMultipartUpload implements S3Client

func (*RealS3Client) DeleteObject

func (r *RealS3Client) DeleteObject(ctx context.Context, input *awss3.DeleteObjectInput, opts ...func(*awss3.Options)) (*awss3.DeleteObjectOutput, error)

DeleteObject implements S3Client

func (*RealS3Client) GetObject

func (r *RealS3Client) GetObject(ctx context.Context, input *awss3.GetObjectInput, opts ...func(*awss3.Options)) (*awss3.GetObjectOutput, error)

GetObject implements S3Client

func (*RealS3Client) HeadObject

func (r *RealS3Client) HeadObject(ctx context.Context, input *awss3.HeadObjectInput, opts ...func(*awss3.Options)) (*awss3.HeadObjectOutput, error)

HeadObject implements S3Client

func (*RealS3Client) ListObjectsV2

func (r *RealS3Client) ListObjectsV2(ctx context.Context, input *awss3.ListObjectsV2Input, opts ...func(*awss3.Options)) (*awss3.ListObjectsV2Output, error)

ListObjectsV2 implements S3Client

func (*RealS3Client) PresignGetObject

func (r *RealS3Client) PresignGetObject(ctx context.Context, input *awss3.GetObjectInput, expires time.Duration) (string, error)

PresignGetObject implements S3Client

func (*RealS3Client) PresignHeadObject

func (r *RealS3Client) PresignHeadObject(ctx context.Context, input *awss3.HeadObjectInput, expires time.Duration) (string, error)

PresignHeadObject implements S3Client Note: pull zone is intentionally NOT applied to HEAD requests. CDNs like Bunny may convert HEAD to GET when proxying, which breaks the SigV4 signature. HEAD responses have no body, so CDN caching provides no benefit.

func (*RealS3Client) PresignPutObject

func (r *RealS3Client) PresignPutObject(ctx context.Context, input *awss3.PutObjectInput, expires time.Duration) (string, error)

PresignPutObject implements S3Client

func (*RealS3Client) PresignUploadPart

func (r *RealS3Client) PresignUploadPart(ctx context.Context, input *awss3.UploadPartInput, expires time.Duration) (string, error)

PresignUploadPart implements S3Client

func (*RealS3Client) PutObject

func (r *RealS3Client) PutObject(ctx context.Context, input *awss3.PutObjectInput, opts ...func(*awss3.Options)) (*awss3.PutObjectOutput, error)

PutObject implements S3Client

type S3Client

type S3Client interface {
	// Multipart upload operations
	CreateMultipartUpload(ctx context.Context, input *awss3.CreateMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.CreateMultipartUploadOutput, error)
	CompleteMultipartUpload(ctx context.Context, input *awss3.CompleteMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.CompleteMultipartUploadOutput, error)
	AbortMultipartUpload(ctx context.Context, input *awss3.AbortMultipartUploadInput, opts ...func(*awss3.Options)) (*awss3.AbortMultipartUploadOutput, error)

	// Direct object operations
	GetObject(ctx context.Context, input *awss3.GetObjectInput, opts ...func(*awss3.Options)) (*awss3.GetObjectOutput, error)
	HeadObject(ctx context.Context, input *awss3.HeadObjectInput, opts ...func(*awss3.Options)) (*awss3.HeadObjectOutput, error)
	PutObject(ctx context.Context, input *awss3.PutObjectInput, opts ...func(*awss3.Options)) (*awss3.PutObjectOutput, error)
	CopyObject(ctx context.Context, input *awss3.CopyObjectInput, opts ...func(*awss3.Options)) (*awss3.CopyObjectOutput, error)
	DeleteObject(ctx context.Context, input *awss3.DeleteObjectInput, opts ...func(*awss3.Options)) (*awss3.DeleteObjectOutput, error)
	ListObjectsV2(ctx context.Context, input *awss3.ListObjectsV2Input, opts ...func(*awss3.Options)) (*awss3.ListObjectsV2Output, error)

	// Presigned URL operations - return URL string directly
	PresignGetObject(ctx context.Context, input *awss3.GetObjectInput, expires time.Duration) (string, error)
	PresignHeadObject(ctx context.Context, input *awss3.HeadObjectInput, expires time.Duration) (string, error)
	PresignPutObject(ctx context.Context, input *awss3.PutObjectInput, expires time.Duration) (string, error)
	PresignUploadPart(ctx context.Context, input *awss3.UploadPartInput, expires time.Duration) (string, error)
}

S3Client defines the S3 operations used by the hold service. This interface allows mocking S3 for tests without real credentials. Use RealS3Client to wrap *s3.Client, or MockS3Client for testing.

type S3Service

type S3Service struct {
	Client     S3Client // S3 client for presigned URLs (interface for testability)
	Bucket     string   // S3 bucket name
	PathPrefix string   // S3 path prefix (if any)
}

S3Service wraps an S3 client for presigned URL generation

func NewS3Service

func NewS3Service(params map[string]any) (*S3Service, error)

NewS3Service initializes the S3 client for presigned URL generation S3 is required - this will return an error if not properly configured

func (*S3Service) Delete

func (s *S3Service) Delete(ctx context.Context, blobPath string) error

Delete removes the object at blobPath.

func (*S3Service) GetBytes

func (s *S3Service) GetBytes(ctx context.Context, blobPath string) ([]byte, error)

GetBytes fetches an object from S3 and returns its contents as bytes.

func (*S3Service) ListPrefix

func (s *S3Service) ListPrefix(ctx context.Context, blobPath string) ([]string, error)

ListPrefix returns immediate children (common prefixes) under blobPath using Delimiter="/".

func (*S3Service) Move

func (s *S3Service) Move(ctx context.Context, srcPath, dstPath string) error

Move copies srcPath to dstPath then deletes srcPath.

func (*S3Service) PutBytes

func (s *S3Service) PutBytes(ctx context.Context, blobPath string, data []byte, contentType string) error

PutBytes uploads data to blobPath with the given content type.

func (*S3Service) Stat

func (s *S3Service) Stat(ctx context.Context, blobPath string) (int64, error)

Stat returns the size of an object at blobPath, or an error if it doesn't exist.

func (*S3Service) WalkBlobs

func (s *S3Service) WalkBlobs(ctx context.Context, prefix string, fn func(key string, size int64) error) error

WalkBlobs paginates ListObjectsV2 under prefix and calls fn for each object. Keys passed to fn have the PathPrefix stripped (same format as BlobPath output).

type UploadPartCall

type UploadPartCall struct {
	Bucket     string
	Key        string
	UploadID   string
	PartNumber int32
}

UploadPartCall records a PresignUploadPart call

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL