Skip to content

Request flow ​

A top-down map of how every supported S3 operation travels through TinyS3: from the HTTP transport, through the S3Handler front-door pipeline, into the operation handlers, down to the S3FileOperations facade and the pluggable FileSystem backend.

This page was generated by reading the dispatch code (S3Handler, BucketHandler, BucketSubresourceHandler, ObjectHandler, ObjectSubresourceHandler, MultipartHandler, and the POST/Select handlers) and reflects the current class layout. The 79 operations below are exactly the files under docs/s3-api-reference/reference/actions/amazon-s3/core/ — the compatibility contract.

Layers ​

LayerPackage(s)
Transport / HTTPdev.totis.tinys3.http (TinyHttpServer, NettyServerHandler, NettyHttpExchange) → builds S3Context (dev.totis.tinys3)
Front doordev.totis.tinys3.S3Handler plus routing (HostRouter, PluginRouteRegistry), cors (CorsPolicy), website (WebsiteHandler), authz (RequestAuthorizer, S3ActionResolver, RequestContextBuilder), auth (BucketPolicyEvaluator)
Operation handlersdev.totis.tinys3 (BucketHandler, BucketSubresourceHandler, ObjectHandler, GetObjectHandler, PutObjectHandler, CopyObjectHandler, ObjectSubresourceHandler, MultipartHandler, DeleteObjectsPostHandler, BucketUploadPostHandler, SelectObjectContentHandler)
Facadedev.totis.tinys3.S3FileOperations / DefaultS3FileOperations and collaborators MultipartStore, BucketConfigOperations, MetadataStore
Storage backenddev.totis.tinys3.filesystem.FileSystem: DiskFileSystem, ErasureCodedFileSystem (file-system), ClusterFileSystem (distributed), PooledFileSystem (pools)

Flow ​

Operation → class ​

Dispatch in S3Handler.handle() keys on query string and object-key presence: ?uploads/uploadId → MultipartHandler; ?versions with empty key → BucketHandler; empty key → BucketHandler (sub-resource query routes to BucketSubresourceHandler); otherwise ObjectHandler. POST form uploads are detected earlier (isPostBucketUpload). Facade calls are all on DefaultS3FileOperations unless noted.

Bucket lifecycle — BucketHandler ​

OperationHTTP (verb + path/query)Handler classFacade methodNotes
ListBucketsGET /BucketHandler.handleListBucketsgetListAllBucketsResultAnonymous returns empty list; ?usage, max-buckets/continuation-token paging
CreateBucketPUT /{bucket}BucketHandler.handleCreateBucketcreateDirectory, saveBucketMetadataLocationConstraint doubles as optional pool pin
DeleteBucketDELETE /{bucket}BucketHandler.handleDeleteBuckethandleDeleteObject, deleteBucketCustomDomain409 BucketNotEmpty if non-empty
HeadBucketHEAD /{bucket}BucketHandler.handleHeadObject (empty key)getObjectLockConfigurationAuthorized as s3:ListBucket
GetBucketLocationGET /{bucket}?locationBucketHandler.handleGetBucketLocationgetBucketMetadata
ListObjectsGET /{bucket}BucketHandler.handleListObjectsgetBucketListResultV1 listing
ListObjectsV2GET /{bucket}?list-type=2BucketHandler.handleListObjectsgetBucketListResultSame handler as V1
ListObjectVersionsGET /{bucket}?versionsBucketHandler.handleListObjectVersionslistObjectVersions

Bucket config sub-resources — BucketSubresourceHandler ​

Authorized once in BucketHandler.handleBucketOperation (bucketConfigSubresource + actionForRequest), then routed. GET/PUT/DELETE share one method per sub-resource; the verb selects read vs write.

OperationHTTP (verb + path/query)Handler classFacade methodNotes
GetBucketVersioningGET /{bucket}?versioninghandleBucketVersioninggetBucketVersioning
PutBucketVersioningPUT /{bucket}?versioninghandleBucketVersioningsetBucketVersioningCannot suspend under object-lock
GetBucketAclGET /{bucket}?aclhandleBucketAclgetBucketMetadata
PutBucketAclPUT /{bucket}?aclhandleBucketAclsaveBucketMetadata
GetBucketPolicyGET /{bucket}?policyhandleBucketPolicygetBucketPolicy
PutBucketPolicyPUT /{bucket}?policyhandleBucketPolicysetBucketPolicyConfirmRemoveSelfBucketAccess tracked
DeleteBucketPolicyDELETE /{bucket}?policyhandleBucketPolicysetBucketPolicy (clear)
GetBucketPolicyStatusGET /{bucket}?policyStatushandleBucketPolicyStatusgetBucketPolicyComputes IsPublic
GetBucketCorsGET /{bucket}?corshandleBucketCorsgetBucketCors
PutBucketCorsPUT /{bucket}?corshandleBucketCorssetBucketCors
DeleteBucketCorsDELETE /{bucket}?corshandleBucketCorssetBucketCors (clear)
GetBucketWebsiteGET /{bucket}?websitehandleBucketWebsitegetBucketWebsite
PutBucketWebsitePUT /{bucket}?websitehandleBucketWebsitesetBucketWebsite
DeleteBucketWebsiteDELETE /{bucket}?websitehandleBucketWebsitesetBucketWebsite (clear)
GetBucketLifecycleGET /{bucket}?lifecyclehandleBucketLifecyclegetBucketLifecycleAlias of below
GetBucketLifecycleConfigurationGET /{bucket}?lifecyclehandleBucketLifecyclegetBucketLifecycle
PutBucketLifecyclePUT /{bucket}?lifecyclehandleBucketLifecyclesetBucketLifecycle
PutBucketLifecycleConfigurationPUT /{bucket}?lifecyclehandleBucketLifecyclesetBucketLifecycle
DeleteBucketLifecycleDELETE /{bucket}?lifecyclehandleBucketLifecyclesetBucketLifecycle (clear)
GetBucketEncryptionGET /{bucket}?encryptionhandleBucketEncryptiongetBucketEncryption
PutBucketEncryptionPUT /{bucket}?encryptionhandleBucketEncryptionsetBucketEncryption
DeleteBucketEncryptionDELETE /{bucket}?encryptionhandleBucketEncryptionsetBucketEncryption (clear)
GetBucketTaggingGET /{bucket}?tagginghandleBucketTagginggetBucketTagging
PutBucketTaggingPUT /{bucket}?tagginghandleBucketTaggingsetBucketTagging
DeleteBucketTaggingDELETE /{bucket}?tagginghandleBucketTaggingsetBucketTagging (clear)
GetBucketNotificationGET /{bucket}?notificationhandleBucketNotificationgetBucketNotificationAlias of below
GetBucketNotificationConfigurationGET /{bucket}?notificationhandleBucketNotificationgetBucketNotification
PutBucketNotificationPUT /{bucket}?notificationhandleBucketNotificationsetBucketNotification
PutBucketNotificationConfigurationPUT /{bucket}?notificationhandleBucketNotificationsetBucketNotification
GetBucketReplicationGET /{bucket}?replicationhandleBucketReplicationgetBucketReplication
PutBucketReplicationPUT /{bucket}?replicationhandleBucketReplicationsetBucketReplicationVersioning required
DeleteBucketReplicationDELETE /{bucket}?replicationhandleBucketReplicationsetBucketReplication (clear)
GetBucketAccelerateConfigurationGET /{bucket}?acceleratehandleBucketAccelerate—Static Suspended response
PutBucketAccelerateConfigurationPUT /{bucket}?acceleratehandleBucketAccelerate—Accepted, not enforced
GetBucketRequestPaymentGET /{bucket}?requestPaymenthandleBucketRequestPaymentgetBucketMetadata
PutBucketRequestPaymentPUT /{bucket}?requestPaymenthandleBucketRequestPaymentsaveBucketMetadata
GetBucketLoggingGET /{bucket}?logginghandleBucketLogginggetBucketMetadata
PutBucketLoggingPUT /{bucket}?logginghandleBucketLoggingsaveBucketMetadata
GetPublicAccessBlockGET /{bucket}?publicAccessBlockhandlePublicAccessBlockgetPublicAccessBlock
PutPublicAccessBlockPUT /{bucket}?publicAccessBlockhandlePublicAccessBlocksetPublicAccessBlock
DeletePublicAccessBlockDELETE /{bucket}?publicAccessBlockhandlePublicAccessBlocksetPublicAccessBlock (clear)
GetObjectLockConfigurationGET /{bucket}?object-lockhandleObjectLockConfigurationgetObjectLockConfiguration
PutObjectLockConfigurationPUT /{bucket}?object-lockhandleObjectLockConfigurationsetObjectLockConfiguration
GetBucketOwnershipControlsGET /{bucket}?ownershipControlshandleOwnershipControlsgetBucketOwnershipControls
PutBucketOwnershipControlsPUT /{bucket}?ownershipControlshandleOwnershipControlssetBucketOwnershipControls
DeleteBucketOwnershipControlsDELETE /{bucket}?ownershipControlshandleOwnershipControlssetBucketOwnershipControls (clear)

Object CRUD — ObjectHandler and delegates ​

OperationHTTP (verb + path/query)Handler classFacade methodNotes
PutObjectPUT /{bucket}/{key}PutObjectHandler.handlePutObjecthandlePutObjectNo x-amz-copy-source header
CopyObjectPUT /{bucket}/{key} + x-amz-copy-sourceCopyObjectHandler.handleCopyObjecthandlePutObject / copy pathHeader selects copy
GetObjectGET /{bucket}/{key}GetObjectHandler.handleGetObjectgetObject / tryFastGetObjectRanges, conditionals, SSE-C; plain GET may take the event-loop fast path in S3Handler.tryFastGet
HeadObjectHEAD /{bucket}/{key}GetObjectHandler.handleHeadObjectgetObjectMetadata
DeleteObjectDELETE /{bucket}/{key}ObjectHandler.handleDeleteObjecthandleDeleteObjectVersionedConditional headers, governance bypass

Object sub-resources — ObjectSubresourceHandler ​

OperationHTTP (verb + path/query)Handler classFacade methodNotes
GetObjectTaggingGET /{bucket}/{key}?tagginghandleObjectTagginggetObjectTags
PutObjectTaggingPUT /{bucket}/{key}?tagginghandleObjectTaggingputObjectTags
DeleteObjectTaggingDELETE /{bucket}/{key}?tagginghandleObjectTaggingdeleteObjectTags
GetObjectAclGET /{bucket}/{key}?aclhandleObjectAclgetObjectMetadata
PutObjectAclPUT /{bucket}/{key}?aclhandleObjectAclsetObjectAcl, setObjectAclGrantsRefused under BucketOwnerEnforced
GetObjectLegalHoldGET /{bucket}/{key}?legal-holdhandleObjectLegalHoldgetObjectLegalHoldObject-lock must be enabled
PutObjectLegalHoldPUT /{bucket}/{key}?legal-holdhandleObjectLegalHoldsetObjectLegalHold
GetObjectRetentionGET /{bucket}/{key}?retentionhandleObjectRetentiongetObjectRetention
PutObjectRetentionPUT /{bucket}/{key}?retentionhandleObjectRetentionsetObjectRetentionWeakening needs governance bypass
GetObjectAttributesGET /{bucket}/{key}?attributeshandleGetObjectAttributesgetObjectMetadata, getVersionedObjectMetadata
RestoreObjectPOST /{bucket}/{key}?restorehandlePostRestoreObject—No real archival tier; immediate restore
GetObjectTorrentGET /{bucket}/{key}?torrenthandleGetObjectTorrent—Legacy; returns 404 NoSuchKey

Multipart — MultipartHandler ​

OperationHTTP (verb + path/query)Handler classFacade methodNotes
CreateMultipartUploadPOST /{bucket}/{key}?uploadshandleMultipartUploadMultipartStore initNon-GET with uploads and no uploadId
ListMultipartUploadsGET /{bucket}?uploadshandleListMultipartUploadsMultipartStore listGET with uploads
UploadPartPUT /{bucket}/{key}?uploadId&partNumberhandleUploadParthandleUploadPart / handleUploadPartChannel
UploadPartCopyPUT /{bucket}/{key}?uploadId&partNumber + x-amz-copy-sourcehandleUploadPartCopyhandleUploadPartChannelHeader selects copy
CompleteMultipartUploadPOST /{bucket}/{key}?uploadIdhandleCompleteMultipartUploadcomplete/assembleRetry-idempotent via completed-upload cache
AbortMultipartUploadDELETE /{bucket}/{key}?uploadIdhandleAbortMultipartUploadhandleAbortMultipartUpload
ListPartsGET /{bucket}/{key}?uploadIdhandleListPartsMultipartStore list parts

Bulk delete — DeleteObjectsPostHandler ​

OperationHTTP (verb + path/query)Handler classFacade methodNotes
DeleteObjectsPOST /{bucket}?deleteDeleteObjectsPostHandler.handleDeleteObjectshandleDeleteObjectVersioned (per key)Dispatched from BucketHandler.handleBucketOperation

POST form upload — BucketUploadPostHandler ​

OperationHTTP (verb + path/query)Handler classFacade methodNotes
PostObject (browser form POST)POST /{bucket} (multipart/form-data)BucketUploadPostHandler.handlehandlePutObjectDetected via S3Context.isPostBucketUpload; POST policy signature. Documented as PutObject in the reference.

S3 Select — SelectObjectContentHandler ​

OperationHTTP (verb + path/query)Handler classFacade methodNotes
SelectObjectContentPOST /{bucket}/{key}?select&select-type=2SelectObjectContentHandler.handleSelectObjectContentgetObject (source read)Query engine: DefaultSelectQueryEngine

TinyS3 is AGPLv3 licensed. Cloudflare and Cloudflare Workers are trademarks of Cloudflare, Inc. Amazon S3 and AWS are trademarks of Amazon.com, Inc. or its affiliates. MinIO is a trademark of MinIO, Inc. They are named only to describe compatibility; totis.ai is not affiliated with, endorsed by, or sponsored by any of them.