s3

package
v0.0.1-alpha.35 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Overview

Package s3 implements the AWS S3 REST API emulator.

S3 uses a REST-style XML API. Each HTTP method+path combination maps to an AWS S3 operation. Sub-resource query parameters (e.g. ?acl, ?cors, ?policy) further specialise the operation. Each sub-resource routes to its own named handler in handler.go, which either implements the operation or returns a clear HTTP 501 with x-emulator-unsupported: true.

Implemented:

GET  /                           → ListBuckets
PUT  /{bucket}                   → CreateBucket
HEAD /{bucket}                   → HeadBucket
DELETE /{bucket}                 → DeleteBucket
GET  /{bucket}?location          → GetBucketLocation
GET  /{bucket}?list-type=2       → ListObjectsV2
PUT  /{bucket}/{key}             → PutObject
PUT  /{bucket}/{key} (+copy hdr) → CopyObject
GET  /{bucket}/{key}             → GetObject
HEAD /{bucket}/{key}             → HeadObject
DELETE /{bucket}/{key}           → DeleteObject

All other operations are routed to named stubs that return HTTP 501. See docs/services/s3.md for the full support matrix.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MarshalBucketEncryption

func MarshalBucketEncryption(rules []BucketEncryptionRule) ([]byte, error)

MarshalBucketEncryption serializes a PutBucketEncryption request.

func MarshalBucketTagging

func MarshalBucketTagging(tags map[string]string) ([]byte, error)

MarshalBucketTagging serializes a PutBucketTagging request.

func MarshalCORSConfiguration

func MarshalCORSConfiguration(rules []CORSRule) ([]byte, error)

MarshalCORSConfiguration serializes a PutBucketCors request.

func MarshalLifecycleConfiguration

func MarshalLifecycleConfiguration(cfg *LifecycleConfiguration) ([]byte, error)

MarshalLifecycleConfiguration serializes the S3 domain model using the same private wire types used by Put/GetBucketLifecycleConfiguration. It is exported for internal service adapters such as CloudFormation; callers still dispatch the result through S3 so that S3 owns validation and state.

func MarshalNotificationConfiguration

func MarshalNotificationConfiguration(cfg *NotificationConfig) ([]byte, error)

MarshalNotificationConfiguration serializes a PutBucketNotificationConfiguration request.

func MarshalVersioningConfiguration

func MarshalVersioningConfiguration(status string) ([]byte, error)

MarshalVersioningConfiguration serializes a PutBucketVersioning request.

func MarshalWebsiteConfiguration

func MarshalWebsiteConfiguration(cfg *WebsiteConfiguration) ([]byte, error)

MarshalWebsiteConfiguration serializes a PutBucketWebsite request.

Types

type Bucket

type Bucket struct {
	Name             string                 `json:"name"`
	Region           string                 `json:"region"`
	CreationDate     time.Time              `json:"creation_date"`
	VersioningStatus string                 `json:"versioning_status,omitempty"` // "Enabled", "Suspended", or ""
	Tags             map[string]string      `json:"tags,omitempty"`
	WebsiteConfig    *WebsiteConfiguration  `json:"website_config,omitempty"`
	CORSRules        []CORSRule             `json:"cors_rules,omitempty"`
	Policy           string                 `json:"policy,omitempty"`
	EncryptionRules  []BucketEncryptionRule `json:"encryption_rules,omitempty"`

	// VersionHistoryReady records that every object already in this bucket has
	// been given a place in s3:versions. See ensureVersionHistory in
	// version.go — it is the completion flag for that backfill, not a feature
	// switch, and it is meaningless on a bucket that is not versioned.
	VersionHistoryReady bool `json:"version_history_ready,omitempty"`
}

Bucket represents a stored S3 bucket.

type BucketEncryptionRule

type BucketEncryptionRule struct {
	SSEAlgorithm     string `json:"sse_algorithm"`
	KMSMasterKeyID   string `json:"kms_master_key_id,omitempty"`
	BucketKeyEnabled *bool  `json:"bucket_key_enabled,omitempty"`
}

type CORSRule

type CORSRule struct {
	AllowedHeaders []string `json:"allowed_headers,omitempty"`
	AllowedMethods []string `json:"allowed_methods"`
	AllowedOrigins []string `json:"allowed_origins"`
	ExposeHeaders  []string `json:"expose_headers,omitempty"`
	MaxAgeSeconds  int      `json:"max_age_seconds,omitempty"`
}

CORSRule stores a single CORS rule for an S3 bucket.

type EventBridgeNotificationConfig

type EventBridgeNotificationConfig struct{}

EventBridgeNotificationConfig enables delivery of the bucket's events to Amazon EventBridge. AWS models it as a structure with no members.

type Handler

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

Handler holds the dependencies for S3 HTTP handlers. All handler methods hang off this struct — this is the standard Go pattern for grouping related handlers (equivalent to a TypeScript class with methods).

func (*Handler) AbortMultipartUpload

func (h *Handler) AbortMultipartUpload(w http.ResponseWriter, r *http.Request)

AbortMultipartUpload handles DELETE /{bucket}/{key}?uploadId=xxx AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html

func (*Handler) BucketDelete

func (h *Handler) BucketDelete(w http.ResponseWriter, r *http.Request)

BucketDelete dispatches DELETE /{bucket} by sub-resource query param.

func (*Handler) BucketGet

func (h *Handler) BucketGet(w http.ResponseWriter, r *http.Request)

BucketGet dispatches GET /{bucket} by sub-resource query param.

func (*Handler) BucketPost

func (h *Handler) BucketPost(w http.ResponseWriter, r *http.Request)

BucketPost dispatches POST /{bucket} by sub-resource query param.

func (*Handler) BucketPut

func (h *Handler) BucketPut(w http.ResponseWriter, r *http.Request)

BucketPut dispatches PUT /{bucket} by sub-resource query param.

func (*Handler) CompleteMultipartUpload

func (h *Handler) CompleteMultipartUpload(w http.ResponseWriter, r *http.Request)

CompleteMultipartUpload handles POST /{bucket}/{key}?uploadId=xxx AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html

func (*Handler) CopyObject

func (h *Handler) CopyObject(w http.ResponseWriter, r *http.Request)

CopyObject handles PUT /{bucket}/{key} with x-amz-copy-source header. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html

func (*Handler) CreateBucket

func (h *Handler) CreateBucket(w http.ResponseWriter, r *http.Request)

func (*Handler) CreateBucketMetadataConfiguration

func (h *Handler) CreateBucketMetadataConfiguration(w http.ResponseWriter, r *http.Request)

CreateBucketMetadataConfiguration handles PUT /{bucket}?metadata AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucketMetadataConfiguration.html

func (*Handler) CreateBucketMetadataTableConfiguration

func (h *Handler) CreateBucketMetadataTableConfiguration(w http.ResponseWriter, r *http.Request)

CreateBucketMetadataTableConfiguration handles POST /{bucket}?metadataTable AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucketMetadataTableConfiguration.html

func (*Handler) CreateMultipartUpload

func (h *Handler) CreateMultipartUpload(w http.ResponseWriter, r *http.Request)

CreateMultipartUpload handles POST /{bucket}/{key}?uploads AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html

func (*Handler) CreateSession

func (h *Handler) CreateSession(w http.ResponseWriter, r *http.Request)

CreateSession handles GET /{bucket}?session AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html

func (*Handler) DeleteBucket

func (h *Handler) DeleteBucket(w http.ResponseWriter, r *http.Request)

DeleteBucket handles DELETE /{bucket} AWS requires the bucket to be empty before deletion.

func (*Handler) DeleteBucketAnalyticsConfiguration

func (h *Handler) DeleteBucketAnalyticsConfiguration(w http.ResponseWriter, r *http.Request)

DeleteBucketAnalyticsConfiguration handles DELETE /{bucket}?analytics AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketAnalyticsConfiguration.html

func (*Handler) DeleteBucketCors

func (h *Handler) DeleteBucketCors(w http.ResponseWriter, r *http.Request)

DeleteBucketCors handles DELETE /{bucket}?cors AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html Implemented in handler_bucket.go.

func (*Handler) DeleteBucketEncryption

func (h *Handler) DeleteBucketEncryption(w http.ResponseWriter, r *http.Request)

DeleteBucketEncryption handles DELETE /{bucket}?encryption.

func (*Handler) DeleteBucketIntelligentTieringConfiguration

func (h *Handler) DeleteBucketIntelligentTieringConfiguration(w http.ResponseWriter, r *http.Request)

DeleteBucketIntelligentTieringConfiguration handles DELETE /{bucket}?intelligent-tiering AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketIntelligentTieringConfiguration.html

func (*Handler) DeleteBucketInventoryConfiguration

func (h *Handler) DeleteBucketInventoryConfiguration(w http.ResponseWriter, r *http.Request)

DeleteBucketInventoryConfiguration handles DELETE /{bucket}?inventory AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketInventoryConfiguration.html

func (*Handler) DeleteBucketLifecycle

func (h *Handler) DeleteBucketLifecycle(w http.ResponseWriter, r *http.Request)

DeleteBucketLifecycle handles DELETE /{bucket}?lifecycle AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketLifecycle.html Implemented in handler_lifecycle.go.

func (*Handler) DeleteBucketMetadataConfiguration

func (h *Handler) DeleteBucketMetadataConfiguration(w http.ResponseWriter, r *http.Request)

DeleteBucketMetadataConfiguration handles DELETE /{bucket}?metadata AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetadataConfiguration.html

func (*Handler) DeleteBucketMetadataTableConfiguration

func (h *Handler) DeleteBucketMetadataTableConfiguration(w http.ResponseWriter, r *http.Request)

DeleteBucketMetadataTableConfiguration handles DELETE /{bucket}?metadataTable AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetadataTableConfiguration.html

func (*Handler) DeleteBucketMetricsConfiguration

func (h *Handler) DeleteBucketMetricsConfiguration(w http.ResponseWriter, r *http.Request)

DeleteBucketMetricsConfiguration handles DELETE /{bucket}?metrics AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketMetricsConfiguration.html

func (*Handler) DeleteBucketOwnershipControls

func (h *Handler) DeleteBucketOwnershipControls(w http.ResponseWriter, r *http.Request)

DeleteBucketOwnershipControls handles DELETE /{bucket}?ownershipControls AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketOwnershipControls.html

func (*Handler) DeleteBucketPolicy

func (h *Handler) DeleteBucketPolicy(w http.ResponseWriter, r *http.Request)

DeleteBucketPolicy handles DELETE /{bucket}?policy AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketPolicy.html

func (*Handler) DeleteBucketReplication

func (h *Handler) DeleteBucketReplication(w http.ResponseWriter, r *http.Request)

DeleteBucketReplication handles DELETE /{bucket}?replication AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketReplication.html

func (*Handler) DeleteBucketTagging

func (h *Handler) DeleteBucketTagging(w http.ResponseWriter, r *http.Request)

DeleteBucketTagging handles DELETE /{bucket}?tagging.

func (*Handler) DeleteBucketWebsite

func (h *Handler) DeleteBucketWebsite(w http.ResponseWriter, r *http.Request)

DeleteBucketWebsite handles DELETE /{bucket}?website AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketWebsite.html Implemented in handler_bucket.go.

func (*Handler) DeleteObject

func (h *Handler) DeleteObject(w http.ResponseWriter, r *http.Request)

DeleteObject handles DELETE /{bucket}/{key}. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html

func (*Handler) DeleteObjectTagging

func (h *Handler) DeleteObjectTagging(w http.ResponseWriter, r *http.Request)

DeleteObjectTagging handles DELETE /{bucket}/{key}?tagging.

func (*Handler) DeleteObjects

func (h *Handler) DeleteObjects(w http.ResponseWriter, r *http.Request)

DeleteObjects handles POST /{bucket}?delete — batch delete up to 1000 keys. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html

func (*Handler) DeletePublicAccessBlock

func (h *Handler) DeletePublicAccessBlock(w http.ResponseWriter, r *http.Request)

DeletePublicAccessBlock handles DELETE /{bucket}?publicAccessBlock AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html

func (*Handler) GetBucketAbac

func (h *Handler) GetBucketAbac(w http.ResponseWriter, r *http.Request)

GetBucketAbac handles GET /{bucket}?abac AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAbac.html

func (*Handler) GetBucketAccelerateConfiguration

func (h *Handler) GetBucketAccelerateConfiguration(w http.ResponseWriter, r *http.Request)

GetBucketAccelerateConfiguration handles GET /{bucket}?accelerate AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAccelerateConfiguration.html

func (*Handler) GetBucketAcl

func (h *Handler) GetBucketAcl(w http.ResponseWriter, r *http.Request)

GetBucketAcl handles GET /{bucket}?acl AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html

func (*Handler) GetBucketCors

func (h *Handler) GetBucketCors(w http.ResponseWriter, r *http.Request)

GetBucketCors handles GET /{bucket}?cors AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html Implemented in handler_bucket.go.

func (*Handler) GetBucketEncryption

func (h *Handler) GetBucketEncryption(w http.ResponseWriter, r *http.Request)

GetBucketEncryption handles GET /{bucket}?encryption.

func (*Handler) GetBucketLifecycleConfiguration

func (h *Handler) GetBucketLifecycleConfiguration(w http.ResponseWriter, r *http.Request)

GetBucketLifecycleConfiguration handles GET /{bucket}?lifecycle Covers both GetBucketLifecycle (deprecated) and GetBucketLifecycleConfiguration. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html Implemented in handler_lifecycle.go.

func (*Handler) GetBucketLocation

func (h *Handler) GetBucketLocation(w http.ResponseWriter, r *http.Request)

GetBucketLocation handles GET /{bucket}?location. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLocation.html

func (*Handler) GetBucketLogging

func (h *Handler) GetBucketLogging(w http.ResponseWriter, r *http.Request)

GetBucketLogging handles GET /{bucket}?logging AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketLogging.html

func (*Handler) GetBucketMetadataConfiguration

func (h *Handler) GetBucketMetadataConfiguration(w http.ResponseWriter, r *http.Request)

GetBucketMetadataConfiguration handles GET /{bucket}?metadata AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetadataConfiguration.html

func (*Handler) GetBucketMetadataTableConfiguration

func (h *Handler) GetBucketMetadataTableConfiguration(w http.ResponseWriter, r *http.Request)

GetBucketMetadataTableConfiguration handles GET /{bucket}?metadataTable AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketMetadataTableConfiguration.html

func (*Handler) GetBucketNotificationConfiguration

func (h *Handler) GetBucketNotificationConfiguration(w http.ResponseWriter, r *http.Request)

GetBucketNotificationConfiguration handles GET /{bucket}?notification.

func (*Handler) GetBucketOwnershipControls

func (h *Handler) GetBucketOwnershipControls(w http.ResponseWriter, r *http.Request)

GetBucketOwnershipControls handles GET /{bucket}?ownershipControls AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketOwnershipControls.html

func (*Handler) GetBucketPolicy

func (h *Handler) GetBucketPolicy(w http.ResponseWriter, r *http.Request)

GetBucketPolicy handles GET /{bucket}?policy AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicy.html

func (*Handler) GetBucketPolicyStatus

func (h *Handler) GetBucketPolicyStatus(w http.ResponseWriter, r *http.Request)

GetBucketPolicyStatus handles GET /{bucket}?policyStatus AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html

func (*Handler) GetBucketReplication

func (h *Handler) GetBucketReplication(w http.ResponseWriter, r *http.Request)

GetBucketReplication handles GET /{bucket}?replication AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html

func (*Handler) GetBucketRequestPayment

func (h *Handler) GetBucketRequestPayment(w http.ResponseWriter, r *http.Request)

GetBucketRequestPayment handles GET /{bucket}?requestPayment AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketRequestPayment.html

func (*Handler) GetBucketTagging

func (h *Handler) GetBucketTagging(w http.ResponseWriter, r *http.Request)

GetBucketTagging handles GET /{bucket}?tagging.

func (*Handler) GetBucketVersioning

func (h *Handler) GetBucketVersioning(w http.ResponseWriter, r *http.Request)

GetBucketVersioning handles GET /{bucket}?versioning. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html

func (*Handler) GetBucketWebsite

func (h *Handler) GetBucketWebsite(w http.ResponseWriter, r *http.Request)

GetBucketWebsite handles GET /{bucket}?website AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketWebsite.html Implemented in handler_bucket.go.

func (*Handler) GetObject

func (h *Handler) GetObject(w http.ResponseWriter, r *http.Request)

GetObject handles GET /{bucket}/{key}. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html

func (*Handler) GetObjectAcl

func (h *Handler) GetObjectAcl(w http.ResponseWriter, r *http.Request)

GetObjectAcl handles GET /{bucket}/{key}?acl AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html

func (*Handler) GetObjectAttributes

func (h *Handler) GetObjectAttributes(w http.ResponseWriter, r *http.Request)

GetObjectAttributes handles GET /{bucket}/{key}?attributes AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html

func (*Handler) GetObjectLegalHold

func (h *Handler) GetObjectLegalHold(w http.ResponseWriter, r *http.Request)

GetObjectLegalHold handles GET /{bucket}/{key}?legal-hold AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLegalHold.html

func (*Handler) GetObjectLockConfiguration

func (h *Handler) GetObjectLockConfiguration(w http.ResponseWriter, r *http.Request)

GetObjectLockConfiguration handles GET /{bucket}?object-lock AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectLockConfiguration.html

func (*Handler) GetObjectRetention

func (h *Handler) GetObjectRetention(w http.ResponseWriter, r *http.Request)

GetObjectRetention handles GET /{bucket}/{key}?retention AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectRetention.html

func (*Handler) GetObjectTagging

func (h *Handler) GetObjectTagging(w http.ResponseWriter, r *http.Request)

GetObjectTagging handles GET /{bucket}/{key}?tagging.

func (*Handler) GetObjectTorrent

func (h *Handler) GetObjectTorrent(w http.ResponseWriter, r *http.Request)

GetObjectTorrent handles GET /{bucket}/{key}?torrent AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTorrent.html

func (*Handler) GetPublicAccessBlock

func (h *Handler) GetPublicAccessBlock(w http.ResponseWriter, r *http.Request)

GetPublicAccessBlock handles GET /{bucket}?publicAccessBlock AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html

func (*Handler) HeadBucket

func (h *Handler) HeadBucket(w http.ResponseWriter, r *http.Request)

HeadBucket handles HEAD /{bucket} Returns 200 if the bucket exists, 404 if not.

func (*Handler) HeadObject

func (h *Handler) HeadObject(w http.ResponseWriter, r *http.Request)

HeadObject handles HEAD /{bucket}/{key} Returns the same headers as GetObject but no body. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html

func (*Handler) ListBucketAnalyticsConfigurations

func (h *Handler) ListBucketAnalyticsConfigurations(w http.ResponseWriter, r *http.Request)

ListBucketAnalyticsConfigurations handles GET /{bucket}?analytics AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketAnalyticsConfigurations.html

func (*Handler) ListBucketIntelligentTieringConfigurations

func (h *Handler) ListBucketIntelligentTieringConfigurations(w http.ResponseWriter, r *http.Request)

ListBucketIntelligentTieringConfigurations handles GET /{bucket}?intelligent-tiering AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketIntelligentTieringConfigurations.html

func (*Handler) ListBucketInventoryConfigurations

func (h *Handler) ListBucketInventoryConfigurations(w http.ResponseWriter, r *http.Request)

ListBucketInventoryConfigurations handles GET /{bucket}?inventory AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketInventoryConfigurations.html

func (*Handler) ListBucketMetricsConfigurations

func (h *Handler) ListBucketMetricsConfigurations(w http.ResponseWriter, r *http.Request)

ListBucketMetricsConfigurations handles GET /{bucket}?metrics AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucketMetricsConfigurations.html

func (*Handler) ListBuckets

func (h *Handler) ListBuckets(w http.ResponseWriter, r *http.Request)

ListBuckets handles GET / — list all buckets owned by the account. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html

func (*Handler) ListDirectoryBuckets

func (h *Handler) ListDirectoryBuckets(w http.ResponseWriter, r *http.Request)

ListDirectoryBuckets handles GET /?directory-buckets AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListDirectoryBuckets.html

func (*Handler) ListMultipartUploads

func (h *Handler) ListMultipartUploads(w http.ResponseWriter, r *http.Request)

ListMultipartUploads handles GET /{bucket}?uploads AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html

Pagination shape (pagination-plan.md G4): in-progress uploads are bounded metadata (storage-access-plan.md's keep-as-is register already lists this op there) — store.listMultipartUploads keeps its existing single Scan, no storage change. Like ListParts, this deliberately does NOT use serviceutil.Paginate/H1: KeyMarker/UploadIdMarker are plain, AWS-documented values (a real object key and a real upload ID), and AWS's resume rule is a compound comparison over both — Key > KeyMarker, OR Key == KeyMarker AND UploadId > UploadIdMarker — not an opaque position a service alone can mint. Wrapping them in an opaque token would also break AWS's documented "any multipart uploads for a key equal to key-marker might also be included" jump-to behavior for a client that constructs its own markers rather than echoing back NextKeyMarker/NextUploadIdMarker.

func (*Handler) ListObjectVersions

func (h *Handler) ListObjectVersions(w http.ResponseWriter, r *http.Request)

ListObjectVersions handles GET /{bucket}?versions. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectVersions.html

func (*Handler) ListObjects

func (h *Handler) ListObjects(w http.ResponseWriter, r *http.Request)

ListObjects handles GET /{bucket} (legacy v1 listing, no list-type param). AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html

Implemented in handler_bucket.go as ListObjectsV1.

func (*Handler) ListObjectsV1

func (h *Handler) ListObjectsV1(w http.ResponseWriter, r *http.Request)

ListObjectsV1 handles GET /{bucket} (no list-type) and GET /{bucket}?list-type=1. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html

func (*Handler) ListObjectsV2

func (h *Handler) ListObjectsV2(w http.ResponseWriter, r *http.Request)

ListObjectsV2 handles GET /{bucket}?list-type=2. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html

func (*Handler) ListObjectsV2OrLocation deprecated

func (h *Handler) ListObjectsV2OrLocation(w http.ResponseWriter, r *http.Request)

ListObjectsV2OrLocation dispatches GET /{bucket} based on query parameters: ?list-type=2 → ListObjectsV2 ?location → GetBucketLocation (no params) → ListObjectsV2 (default)

Deprecated: use BucketGet which handles all S3 bucket-level query params.

func (*Handler) ListParts

func (h *Handler) ListParts(w http.ResponseWriter, r *http.Request)

ListParts handles GET /{bucket}/{key}?uploadId=xxx AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html

Pagination shape (pagination-plan.md G4): parts are bounded (AWS caps a single multipart upload at 10,000 parts), so this is exactly the boundedness rule's "simple in-memory slice pagination is correct" case — no ScanPage/storage change needed (store.listParts already Scans once and sorts). It deliberately does NOT use serviceutil.Paginate/H1: AWS types PartNumberMarker/NextPartNumberMarker as real integers on the wire (the part number itself, not an opaque cursor), so Paginate's base64(JSON) token would be the wrong shape here — a client (or another SDK) is entitled to jump to an arbitrary part-number-marker without having been handed a NextPartNumberMarker first, which an opaque token can't support.

func (*Handler) ObjectDelete

func (h *Handler) ObjectDelete(w http.ResponseWriter, r *http.Request)

ObjectDelete dispatches DELETE /{bucket}/{key} by sub-resource query param.

func (*Handler) ObjectGet

func (h *Handler) ObjectGet(w http.ResponseWriter, r *http.Request)

ObjectGet dispatches GET /{bucket}/{key} by sub-resource query param.

func (*Handler) ObjectPost

func (h *Handler) ObjectPost(w http.ResponseWriter, r *http.Request)

ObjectPost dispatches POST /{bucket}/{key} by sub-resource query param. POST on an object is only an operation when a subresource selects one — ?uploads, ?uploadId=, ?restore, ?select. Without one there is no such AWS operation, so the fallback is MethodNotAllowed rather than NotImplemented: the latter would claim a gap in this emulator for a request real S3 refuses too, sending a caller after a workaround that does not exist.

func (*Handler) PutBucketAbac

func (h *Handler) PutBucketAbac(w http.ResponseWriter, r *http.Request)

PutBucketAbac handles PUT /{bucket}?abac AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAbac.html

func (*Handler) PutBucketAccelerateConfiguration

func (h *Handler) PutBucketAccelerateConfiguration(w http.ResponseWriter, r *http.Request)

PutBucketAccelerateConfiguration handles PUT /{bucket}?accelerate AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAccelerateConfiguration.html

func (*Handler) PutBucketAcl

func (h *Handler) PutBucketAcl(w http.ResponseWriter, r *http.Request)

PutBucketAcl handles PUT /{bucket}?acl AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html

func (*Handler) PutBucketAnalyticsConfiguration

func (h *Handler) PutBucketAnalyticsConfiguration(w http.ResponseWriter, r *http.Request)

PutBucketAnalyticsConfiguration handles PUT /{bucket}?analytics AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAnalyticsConfiguration.html

func (*Handler) PutBucketCors

func (h *Handler) PutBucketCors(w http.ResponseWriter, r *http.Request)

PutBucketCors handles PUT /{bucket}?cors AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html Implemented in handler_bucket.go.

func (*Handler) PutBucketEncryption

func (h *Handler) PutBucketEncryption(w http.ResponseWriter, r *http.Request)

PutBucketEncryption handles PUT /{bucket}?encryption.

func (*Handler) PutBucketIntelligentTieringConfiguration

func (h *Handler) PutBucketIntelligentTieringConfiguration(w http.ResponseWriter, r *http.Request)

PutBucketIntelligentTieringConfiguration handles PUT /{bucket}?intelligent-tiering AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketIntelligentTieringConfiguration.html

func (*Handler) PutBucketInventoryConfiguration

func (h *Handler) PutBucketInventoryConfiguration(w http.ResponseWriter, r *http.Request)

PutBucketInventoryConfiguration handles PUT /{bucket}?inventory AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketInventoryConfiguration.html

func (*Handler) PutBucketLifecycleConfiguration

func (h *Handler) PutBucketLifecycleConfiguration(w http.ResponseWriter, r *http.Request)

PutBucketLifecycleConfiguration handles PUT /{bucket}?lifecycle Covers both PutBucketLifecycle (deprecated) and PutBucketLifecycleConfiguration. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html Implemented in handler_lifecycle.go.

func (*Handler) PutBucketLogging

func (h *Handler) PutBucketLogging(w http.ResponseWriter, r *http.Request)

PutBucketLogging handles PUT /{bucket}?logging AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html

func (*Handler) PutBucketMetricsConfiguration

func (h *Handler) PutBucketMetricsConfiguration(w http.ResponseWriter, r *http.Request)

PutBucketMetricsConfiguration handles PUT /{bucket}?metrics AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketMetricsConfiguration.html

func (*Handler) PutBucketNotificationConfiguration

func (h *Handler) PutBucketNotificationConfiguration(w http.ResponseWriter, r *http.Request)

PutBucketNotificationConfiguration handles PUT /{bucket}?notification.

func (*Handler) PutBucketOwnershipControls

func (h *Handler) PutBucketOwnershipControls(w http.ResponseWriter, r *http.Request)

PutBucketOwnershipControls handles PUT /{bucket}?ownershipControls AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketOwnershipControls.html

func (*Handler) PutBucketPolicy

func (h *Handler) PutBucketPolicy(w http.ResponseWriter, r *http.Request)

PutBucketPolicy handles PUT /{bucket}?policy AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html

func (*Handler) PutBucketReplication

func (h *Handler) PutBucketReplication(w http.ResponseWriter, r *http.Request)

PutBucketReplication handles PUT /{bucket}?replication AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html

func (*Handler) PutBucketRequestPayment

func (h *Handler) PutBucketRequestPayment(w http.ResponseWriter, r *http.Request)

PutBucketRequestPayment handles PUT /{bucket}?requestPayment AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketRequestPayment.html

func (*Handler) PutBucketTagging

func (h *Handler) PutBucketTagging(w http.ResponseWriter, r *http.Request)

PutBucketTagging handles PUT /{bucket}?tagging.

func (*Handler) PutBucketVersioning

func (h *Handler) PutBucketVersioning(w http.ResponseWriter, r *http.Request)

PutBucketVersioning handles PUT /{bucket}?versioning. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html

The three states are not a simple on/off. A bucket starts with no status at all and has never had versions; Enabled mints a version id for every write; Suspended keeps the versions already recorded and writes new objects as the null version, which is a different thing from returning to the unversioned state — that transition does not exist on AWS and does not exist here.

func (*Handler) PutBucketWebsite

func (h *Handler) PutBucketWebsite(w http.ResponseWriter, r *http.Request)

PutBucketWebsite handles PUT /{bucket}?website AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html Implemented in handler_bucket.go.

func (*Handler) PutObject

func (h *Handler) PutObject(w http.ResponseWriter, r *http.Request)

PutObject handles PUT /{bucket}/{key}. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html

func (*Handler) PutObjectAcl

func (h *Handler) PutObjectAcl(w http.ResponseWriter, r *http.Request)

PutObjectAcl handles PUT /{bucket}/{key}?acl AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectAcl.html

func (*Handler) PutObjectLegalHold

func (h *Handler) PutObjectLegalHold(w http.ResponseWriter, r *http.Request)

PutObjectLegalHold handles PUT /{bucket}/{key}?legal-hold AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectLegalHold.html

func (*Handler) PutObjectLockConfiguration

func (h *Handler) PutObjectLockConfiguration(w http.ResponseWriter, r *http.Request)

PutObjectLockConfiguration handles PUT /{bucket}?object-lock AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectLockConfiguration.html

func (*Handler) PutObjectOrCopy

func (h *Handler) PutObjectOrCopy(w http.ResponseWriter, r *http.Request)

PutObjectOrCopy dispatches PUT /{bucket}/{key}. partNumber is checked first because it requires a secondary header discriminant that the route table can't express. All other sub-resources use the table.

func (*Handler) PutObjectRetention

func (h *Handler) PutObjectRetention(w http.ResponseWriter, r *http.Request)

PutObjectRetention handles PUT /{bucket}/{key}?retention AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectRetention.html

func (*Handler) PutObjectTagging

func (h *Handler) PutObjectTagging(w http.ResponseWriter, r *http.Request)

PutObjectTagging handles PUT /{bucket}/{key}?tagging.

func (*Handler) PutPublicAccessBlock

func (h *Handler) PutPublicAccessBlock(w http.ResponseWriter, r *http.Request)

PutPublicAccessBlock handles PUT /{bucket}?publicAccessBlock AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutPublicAccessBlock.html

func (*Handler) RenameObject

func (h *Handler) RenameObject(w http.ResponseWriter, r *http.Request)

RenameObject handles PUT /{bucket}/{key}?rename AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html

func (*Handler) RestoreObject

func (h *Handler) RestoreObject(w http.ResponseWriter, r *http.Request)

RestoreObject handles POST /{bucket}/{key}?restore AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html

func (*Handler) RootGet

func (h *Handler) RootGet(w http.ResponseWriter, r *http.Request)

RootGet dispatches GET / — either ListBuckets or ListDirectoryBuckets.

func (*Handler) SelectObjectContent

func (h *Handler) SelectObjectContent(w http.ResponseWriter, r *http.Request)

SelectObjectContent handles POST /{bucket}/{key}?select&select-type=2 AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_SelectObjectContent.html

func (*Handler) UpdateBucketMetadataTableConfiguration

func (h *Handler) UpdateBucketMetadataTableConfiguration(w http.ResponseWriter, r *http.Request)

UpdateBucketMetadataTableConfiguration handles PUT /{bucket}?metadataTable Covers UpdateBucketMetadataInventoryTableConfiguration and UpdateBucketMetadataJournalTableConfiguration. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UpdateBucketMetadataInventoryTableConfiguration.html

func (*Handler) UpdateObjectEncryption

func (h *Handler) UpdateObjectEncryption(w http.ResponseWriter, r *http.Request)

UpdateObjectEncryption handles PUT /{bucket}/{key}?encryption AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UpdateObjectEncryption.html

func (*Handler) UploadPart

func (h *Handler) UploadPart(w http.ResponseWriter, r *http.Request)

UploadPart handles PUT /{bucket}/{key}?partNumber=N&uploadId=xxx AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html

func (*Handler) UploadPartCopy

func (h *Handler) UploadPartCopy(w http.ResponseWriter, r *http.Request)

UploadPartCopy handles PUT /{bucket}/{key}?partNumber=N with x-amz-copy-source header. AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html

func (*Handler) WriteGetObjectResponse

func (h *Handler) WriteGetObjectResponse(w http.ResponseWriter, r *http.Request)

WriteGetObjectResponse handles POST /{bucket}/{key}?writeGetObjectResponse AWS docs: https://docs.aws.amazon.com/AmazonS3/latest/API/API_WriteGetObjectResponse.html

type LambdaNotificationConfig

type LambdaNotificationConfig struct {
	ID     string              `json:"id"`
	ARN    string              `json:"arn"` // Lambda function ARN
	Events []string            `json:"events"`
	Filter *NotificationFilter `json:"filter,omitempty"`
}

LambdaNotificationConfig maps one set of S3 events to a Lambda function ARN.

type LifecycleAbortMPU

type LifecycleAbortMPU struct {
	DaysAfterInitiation int `json:"days_after_initiation"`
}

LifecycleAbortMPU aborts multipart uploads left in progress too long.

type LifecycleAnd

type LifecycleAnd struct {
	Prefix                string         `json:"prefix,omitempty"`
	Tags                  []LifecycleTag `json:"tags,omitempty"`
	ObjectSizeGreaterThan *int64         `json:"object_size_greater_than,omitempty"`
	ObjectSizeLessThan    *int64         `json:"object_size_less_than,omitempty"`
}

LifecycleAnd is the conjunction form of a filter.

type LifecycleConfiguration

type LifecycleConfiguration struct {
	Rules []LifecycleRule `json:"rules"`

	// TransitionDefaultMinimumObjectSize carries the
	// x-amz-transition-default-minimum-object-size parameter, which
	// PutBucketLifecycleConfiguration takes as a request header rather than in
	// the body. Empty means the caller supplied none, which reads as AWS's
	// default — see transitionDefaultMinimum.
	TransitionDefaultMinimumObjectSize string `json:"transition_default_minimum_object_size,omitempty"`
}

LifecycleConfiguration is a bucket's stored lifecycle rules.

type LifecycleExpiration

type LifecycleExpiration struct {
	Days                      int        `json:"days,omitempty"`
	Date                      *time.Time `json:"date,omitempty"`
	ExpiredObjectDeleteMarker bool       `json:"expired_object_delete_marker,omitempty"`
}

LifecycleExpiration deletes matching objects. Exactly one of Days, Date and ExpiredObjectDeleteMarker is set — AWS rejects a rule carrying more.

ExpiredObjectDeleteMarker is not an age at all: it removes a delete marker that has become the only version of its key, which is the tidy-up AWS offers for a versioned bucket whose noncurrent versions have already expired away beneath their marker.

type LifecycleFilter

type LifecycleFilter struct {
	Prefix                string        `json:"prefix,omitempty"`
	Tag                   *LifecycleTag `json:"tag,omitempty"`
	ObjectSizeGreaterThan *int64        `json:"object_size_greater_than,omitempty"`
	ObjectSizeLessThan    *int64        `json:"object_size_less_than,omitempty"`
	And                   *LifecycleAnd `json:"and,omitempty"`
}

LifecycleFilter selects which objects a rule applies to. AWS models it as a union: at most one of the fields below is set, with And carrying the conjunction of several predicates.

type LifecycleNoncurrentVersionExpiration

type LifecycleNoncurrentVersionExpiration struct {
	NoncurrentDays          int  `json:"noncurrent_days"`
	NewerNoncurrentVersions *int `json:"newer_noncurrent_versions,omitempty"`
}

LifecycleNoncurrentVersionExpiration permanently removes versions that have been noncurrent for NoncurrentDays.

NewerNoncurrentVersions is how many noncurrent versions must sit above one before it is eligible — "retain this many, then start expiring" — and is nil when the caller set none, which AWS reads as zero.

type LifecycleNoncurrentVersionTransition

type LifecycleNoncurrentVersionTransition struct {
	NoncurrentDays          int    `json:"noncurrent_days"`
	NewerNoncurrentVersions *int   `json:"newer_noncurrent_versions,omitempty"`
	StorageClass            string `json:"storage_class"`
}

LifecycleNoncurrentVersionTransition marks noncurrent versions with a storage class, on the same eligibility rules as the expiration above.

type LifecycleRule

type LifecycleRule struct {
	ID     string `json:"id"`
	Status string `json:"status"` // "Enabled" or "Disabled"

	Prefix *string          `json:"prefix,omitempty"`
	Filter *LifecycleFilter `json:"filter,omitempty"`

	Expiration                     *LifecycleExpiration                   `json:"expiration,omitempty"`
	NoncurrentVersionExpiration    *LifecycleNoncurrentVersionExpiration  `json:"noncurrent_version_expiration,omitempty"`
	NoncurrentVersionTransitions   []LifecycleNoncurrentVersionTransition `json:"noncurrent_version_transitions,omitempty"`
	Transitions                    []LifecycleTransition                  `json:"transitions,omitempty"`
	AbortIncompleteMultipartUpload *LifecycleAbortMPU                     `json:"abort_incomplete_multipart_upload,omitempty"`
}

LifecycleRule is one lifecycle rule.

Exactly one of Prefix and Filter is non-nil: Prefix is the deprecated rule-level form (still what the CLI's simplest example emits), Filter the current one. AWS refuses a rule carrying both, and echoes back whichever form was supplied rather than rewriting one into the other — so both are modelled rather than normalised.

type LifecycleTag

type LifecycleTag struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

LifecycleTag is one object-tag predicate.

type LifecycleTransition

type LifecycleTransition struct {
	Days         int        `json:"days,omitempty"`
	Date         *time.Time `json:"date,omitempty"`
	StorageClass string     `json:"storage_class"`
}

LifecycleTransition marks matching objects with a storage class. Exactly one of Days and Date is set.

type MultipartUpload

type MultipartUpload struct {
	UploadID    string            `json:"upload_id"`
	Bucket      string            `json:"bucket"`
	Key         string            `json:"key"`
	ContentType string            `json:"content_type"`
	Metadata    map[string]string `json:"metadata,omitempty"`
	Initiated   time.Time         `json:"initiated"`
}

MultipartUpload tracks an initiated multipart upload before completion.

type NotificationConfig

type NotificationConfig struct {
	QueueConfigurations  []QueueNotificationConfig  `json:"queue_configurations,omitempty"`
	LambdaConfigurations []LambdaNotificationConfig `json:"lambda_configurations,omitempty"`
	TopicConfigurations  []TopicNotificationConfig  `json:"topic_configurations,omitempty"`

	// EventBridgeConfiguration mirrors com.amazonaws.s3#EventBridgeConfiguration,
	// which is an empty structure: its presence is the whole signal, and while
	// it is set S3 sends every object event to the default event bus with no
	// event-type or key filtering. A pointer models that presence; the struct
	// stays empty so a future member lands here rather than changing the shape.
	EventBridgeConfiguration *EventBridgeNotificationConfig `json:"event_bridge_configuration,omitempty"`
}

NotificationConfig is the top-level structure stored per bucket. It mirrors the AWS S3 NotificationConfiguration XML schema.

type NotificationDispatcher

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

NotificationDispatcher reads per-bucket notification configs and routes matched events to destination sinks (SQS, SNS, Lambda).

func NewNotificationDispatcher

func NewNotificationDispatcher(
	store *s3Store,
	enqueuer events.MessageEnqueuer,
	invoker events.FunctionInvoker,
	eventBus events.BusPublisher,
	bus *events.Bus,
	logger *zap.Logger,
	region string,
) (d *NotificationDispatcher, cancel func())

NewNotificationDispatcher creates a dispatcher and subscribes it to the given event bus for all S3 event types. The returned cancel function removes the subscriptions (useful in tests).

invoker is nil only when wired without Lambda (tests); Lambda notification configs will be skipped in that case. eventBus is nil only when wired without EventBridge, and EventBridge configurations are skipped then.

type NotificationFilter

type NotificationFilter struct {
	Key NotificationFilterKey `json:"key"`
}

NotificationFilter holds key-based filter rules.

type NotificationFilterKey

type NotificationFilterKey struct {
	Rules []NotificationFilterRule `json:"rules,omitempty"`
}

NotificationFilterKey is the S3Key element that contains filter rules.

type NotificationFilterRule

type NotificationFilterRule struct {
	Name  string `json:"name"` // "prefix" or "suffix"
	Value string `json:"value"`
}

NotificationFilterRule is a single prefix/suffix filter.

type Object

type Object struct {
	Bucket             string            `json:"bucket"`
	Key                string            `json:"key"`
	Body               []byte            `json:"-"`
	ContentType        string            `json:"content_type"`
	ContentLength      int64             `json:"content_length"`
	ETag               string            `json:"etag"`
	LastModified       time.Time         `json:"last_modified"`
	Metadata           map[string]string `json:"metadata,omitempty"`
	Tags               map[string]string `json:"tags,omitempty"`
	ContentDisposition string            `json:"content_disposition,omitempty"`
	ContentEncoding    string            `json:"content_encoding,omitempty"`
	ContentLanguage    string            `json:"content_language,omitempty"`
	CacheControl       string            `json:"cache_control,omitempty"`
	Expires            string            `json:"expires,omitempty"`
	// StorageClass is empty for an object that has never been given one,
	// which reads as STANDARD. A lifecycle Transition sets it as a synthetic
	// marker — no bytes move (docs/plans/full-emulation-priority.md §7).
	StorageClass string `json:"storage_class,omitempty"`

	// VersionID is the version id S3 reports for this version, or "" for the
	// null version — the one AWS gives an object stored while its bucket was
	// unversioned or version-suspended. See version.go.
	VersionID string `json:"version_id,omitempty"`

	// Seq orders a key's versions newest-first and forms the s3:versions
	// storage key. Empty on a record written before version history existed,
	// and on every object in a bucket that has never been versioned.
	Seq string `json:"seq,omitempty"`

	// DeleteMarker marks this version as a delete marker: a version with no
	// body that hides the versions beneath it. See version.go.
	DeleteMarker bool `json:"delete_marker,omitempty"`

	// IsLatest is derived at list time, never stored: which version is current
	// is a property of the key's history, not of one record, and persisting it
	// would be a second source of truth to keep in step.
	IsLatest bool `json:"-"`
}

Object represents a stored S3 object. Body is stored on disk, not in the state store — the json:"-" tag excludes it from serialisation. Use s3Store.putObject/getObject to handle body persistence transparently.

type Part

type Part struct {
	PartNumber   int       `json:"part_number"`
	ETag         string    `json:"etag"`
	Size         int64     `json:"size"`
	LastModified time.Time `json:"last_modified"`
}

Part holds the metadata for one uploaded part. The body is stored on disk at partBodyPath(uploadID, partNumber).

type QueueNotificationConfig

type QueueNotificationConfig struct {
	ID     string              `json:"id"`
	ARN    string              `json:"arn"` // SQS queue ARN
	Events []string            `json:"events"`
	Filter *NotificationFilter `json:"filter,omitempty"`
}

QueueNotificationConfig maps one set of S3 events to an SQS queue ARN.

type Service

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

Service implements router.Service for S3.

func New

func New(cfg *config.Config, store state.Store, logger *zap.Logger, clk clock.Clock, bus *events.Bus) *Service

New returns a configured S3 Service ready to be registered. bus is the shared event bus; pass events.NewBus() from the router.

Starting the lifecycle sweeper here costs one goroutine parked on a ticker — it reads nothing from the store until its first tick, so New stays free of blocking work (AGENTS.md startup budget).

func (*Service) GetObjectBytes

func (s *Service) GetObjectBytes(ctx context.Context, bucket, key, versionID string) ([]byte, *protocol.AWSError)

GetObjectBytes returns the full body of an S3 object for internal callers such as the Lambda S3-reactive sync watcher and Lambda's deployment-package fetch. An empty versionID reads the key's current version; otherwise it reads exactly that version, which is what Lambda's Code.S3ObjectVersion names. Returns an error if the bucket, key or version does not exist — the same errors GetObject answers with over HTTP, so callers can translate one set.

func (*Service) InitNotifications

func (s *Service) InitNotifications(enqueuer events.MessageEnqueuer, invoker events.FunctionInvoker, eventBus events.BusPublisher, bus *events.Bus, logger *zap.Logger)

InitNotifications wires up the S3 event notification dispatcher. Call this after constructing the S3, SQS, Lambda and EventBridge services so the router can pass their narrow sink interfaces without creating an import cycle between services.

invoker is nil only in tests that wire notifications without Lambda, and eventBus only in tests that wire them without EventBridge.

func (*Service) Name

func (s *Service) Name() string

Name satisfies router.Service.

func (*Service) RegisterRoutes

func (s *Service) RegisterRoutes(r chi.Router)

RegisterRoutes mounts all S3 endpoints onto the given router. Route order matters in chi — more specific routes must come before wildcards. Every route delegates to a named dispatcher or handler; there are no inline protocol.NotImplementedXML calls here.

func (*Service) Stop

func (s *Service) Stop(ctx context.Context)

Stop cancels the lifecycle sweeper and waits for it to drain, so shutdown does not return while a sweep is still deleting objects and rewriting metadata. Satisfies router.Stopper.

ctx is the shutdown deadline: if the sweeper has not finished by the time it expires, Stop gives up waiting and says so rather than blocking the process from exiting. The sweep loop checks ctx.Err() between buckets and between objects, so cancellation normally ends it within one object.

type TopicNotificationConfig

type TopicNotificationConfig struct {
	ID     string              `json:"id"`
	ARN    string              `json:"arn"` // SNS topic ARN
	Events []string            `json:"events"`
	Filter *NotificationFilter `json:"filter,omitempty"`
}

TopicNotificationConfig maps one set of S3 events to an SNS topic ARN.

type WebsiteConfiguration

type WebsiteConfiguration struct {
	IndexDocument         string               `json:"index_document,omitempty"`
	ErrorDocument         string               `json:"error_document,omitempty"`
	RedirectAllRequestsTo *WebsiteRedirectAll  `json:"redirect_all_requests_to,omitempty"`
	RoutingRules          []WebsiteRoutingRule `json:"routing_rules,omitempty"`
}

WebsiteConfiguration stores S3 website configuration for a bucket.

It mirrors com.amazonaws.s3#WebsiteConfiguration: either RedirectAllRequestsTo on its own, or IndexDocument with an optional ErrorDocument and optional RoutingRules. handler_website.go enforces the exclusion, so a stored configuration never carries both forms.

type WebsiteRedirect

type WebsiteRedirect struct {
	HostName             string `json:"host_name,omitempty"`
	HTTPRedirectCode     string `json:"http_redirect_code,omitempty"`
	Protocol             string `json:"protocol,omitempty"`
	ReplaceKeyPrefixWith string `json:"replace_key_prefix_with,omitempty"`
	ReplaceKeyWith       string `json:"replace_key_with,omitempty"`
}

WebsiteRedirect is where a routing rule sends a matching request. At least one field is set, and ReplaceKeyWith and ReplaceKeyPrefixWith are mutually exclusive.

type WebsiteRedirectAll

type WebsiteRedirectAll struct {
	HostName string `json:"host_name"`
	Protocol string `json:"protocol,omitempty"`
}

WebsiteRedirectAll redirects every request to the bucket's website endpoint. HostName is required; Protocol is com.amazonaws.s3#Protocol (http | https) and is empty when the caller omitted it.

type WebsiteRoutingCondition

type WebsiteRoutingCondition struct {
	HTTPErrorCodeReturnedEquals string `json:"http_error_code_returned_equals,omitempty"`
	KeyPrefixEquals             string `json:"key_prefix_equals,omitempty"`
}

WebsiteRoutingCondition selects the requests a routing rule redirects. At least one predicate is set; both together mean both must hold.

type WebsiteRoutingRule

type WebsiteRoutingRule struct {
	Condition *WebsiteRoutingCondition `json:"condition,omitempty"`
	Redirect  WebsiteRedirect          `json:"redirect"`
}

WebsiteRoutingRule is one conditional redirect. Condition is optional; a rule without one applies to every request.

Jump to

Keyboard shortcuts

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