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
| Layer | Package(s) |
|---|---|
| Transport / HTTP | dev.totis.tinys3.http (TinyHttpServer, NettyServerHandler, NettyHttpExchange) → builds S3Context (dev.totis.tinys3) |
| Front door | dev.totis.tinys3.S3Handler plus routing (HostRouter, PluginRouteRegistry), cors (CorsPolicy), website (WebsiteHandler), authz (RequestAuthorizer, S3ActionResolver, RequestContextBuilder), auth (BucketPolicyEvaluator) |
| Operation handlers | dev.totis.tinys3 (BucketHandler, BucketSubresourceHandler, ObjectHandler, GetObjectHandler, PutObjectHandler, CopyObjectHandler, ObjectSubresourceHandler, MultipartHandler, DeleteObjectsPostHandler, BucketUploadPostHandler, SelectObjectContentHandler) |
| Facade | dev.totis.tinys3.S3FileOperations / DefaultS3FileOperations and collaborators MultipartStore, BucketConfigOperations, MetadataStore |
| Storage backend | dev.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
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| ListBuckets | GET / | BucketHandler.handleListBuckets | getListAllBucketsResult | Anonymous returns empty list; ?usage, max-buckets/continuation-token paging |
| CreateBucket | PUT /{bucket} | BucketHandler.handleCreateBucket | createDirectory, saveBucketMetadata | LocationConstraint doubles as optional pool pin |
| DeleteBucket | DELETE /{bucket} | BucketHandler.handleDeleteBucket | handleDeleteObject, deleteBucketCustomDomain | 409 BucketNotEmpty if non-empty |
| HeadBucket | HEAD /{bucket} | BucketHandler.handleHeadObject (empty key) | getObjectLockConfiguration | Authorized as s3:ListBucket |
| GetBucketLocation | GET /{bucket}?location | BucketHandler.handleGetBucketLocation | getBucketMetadata | |
| ListObjects | GET /{bucket} | BucketHandler.handleListObjects | getBucketListResult | V1 listing |
| ListObjectsV2 | GET /{bucket}?list-type=2 | BucketHandler.handleListObjects | getBucketListResult | Same handler as V1 |
| ListObjectVersions | GET /{bucket}?versions | BucketHandler.handleListObjectVersions | listObjectVersions |
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.
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| GetBucketVersioning | GET /{bucket}?versioning | handleBucketVersioning | getBucketVersioning | |
| PutBucketVersioning | PUT /{bucket}?versioning | handleBucketVersioning | setBucketVersioning | Cannot suspend under object-lock |
| GetBucketAcl | GET /{bucket}?acl | handleBucketAcl | getBucketMetadata | |
| PutBucketAcl | PUT /{bucket}?acl | handleBucketAcl | saveBucketMetadata | |
| GetBucketPolicy | GET /{bucket}?policy | handleBucketPolicy | getBucketPolicy | |
| PutBucketPolicy | PUT /{bucket}?policy | handleBucketPolicy | setBucketPolicy | ConfirmRemoveSelfBucketAccess tracked |
| DeleteBucketPolicy | DELETE /{bucket}?policy | handleBucketPolicy | setBucketPolicy (clear) | |
| GetBucketPolicyStatus | GET /{bucket}?policyStatus | handleBucketPolicyStatus | getBucketPolicy | Computes IsPublic |
| GetBucketCors | GET /{bucket}?cors | handleBucketCors | getBucketCors | |
| PutBucketCors | PUT /{bucket}?cors | handleBucketCors | setBucketCors | |
| DeleteBucketCors | DELETE /{bucket}?cors | handleBucketCors | setBucketCors (clear) | |
| GetBucketWebsite | GET /{bucket}?website | handleBucketWebsite | getBucketWebsite | |
| PutBucketWebsite | PUT /{bucket}?website | handleBucketWebsite | setBucketWebsite | |
| DeleteBucketWebsite | DELETE /{bucket}?website | handleBucketWebsite | setBucketWebsite (clear) | |
| GetBucketLifecycle | GET /{bucket}?lifecycle | handleBucketLifecycle | getBucketLifecycle | Alias of below |
| GetBucketLifecycleConfiguration | GET /{bucket}?lifecycle | handleBucketLifecycle | getBucketLifecycle | |
| PutBucketLifecycle | PUT /{bucket}?lifecycle | handleBucketLifecycle | setBucketLifecycle | |
| PutBucketLifecycleConfiguration | PUT /{bucket}?lifecycle | handleBucketLifecycle | setBucketLifecycle | |
| DeleteBucketLifecycle | DELETE /{bucket}?lifecycle | handleBucketLifecycle | setBucketLifecycle (clear) | |
| GetBucketEncryption | GET /{bucket}?encryption | handleBucketEncryption | getBucketEncryption | |
| PutBucketEncryption | PUT /{bucket}?encryption | handleBucketEncryption | setBucketEncryption | |
| DeleteBucketEncryption | DELETE /{bucket}?encryption | handleBucketEncryption | setBucketEncryption (clear) | |
| GetBucketTagging | GET /{bucket}?tagging | handleBucketTagging | getBucketTagging | |
| PutBucketTagging | PUT /{bucket}?tagging | handleBucketTagging | setBucketTagging | |
| DeleteBucketTagging | DELETE /{bucket}?tagging | handleBucketTagging | setBucketTagging (clear) | |
| GetBucketNotification | GET /{bucket}?notification | handleBucketNotification | getBucketNotification | Alias of below |
| GetBucketNotificationConfiguration | GET /{bucket}?notification | handleBucketNotification | getBucketNotification | |
| PutBucketNotification | PUT /{bucket}?notification | handleBucketNotification | setBucketNotification | |
| PutBucketNotificationConfiguration | PUT /{bucket}?notification | handleBucketNotification | setBucketNotification | |
| GetBucketReplication | GET /{bucket}?replication | handleBucketReplication | getBucketReplication | |
| PutBucketReplication | PUT /{bucket}?replication | handleBucketReplication | setBucketReplication | Versioning required |
| DeleteBucketReplication | DELETE /{bucket}?replication | handleBucketReplication | setBucketReplication (clear) | |
| GetBucketAccelerateConfiguration | GET /{bucket}?accelerate | handleBucketAccelerate | — | Static Suspended response |
| PutBucketAccelerateConfiguration | PUT /{bucket}?accelerate | handleBucketAccelerate | — | Accepted, not enforced |
| GetBucketRequestPayment | GET /{bucket}?requestPayment | handleBucketRequestPayment | getBucketMetadata | |
| PutBucketRequestPayment | PUT /{bucket}?requestPayment | handleBucketRequestPayment | saveBucketMetadata | |
| GetBucketLogging | GET /{bucket}?logging | handleBucketLogging | getBucketMetadata | |
| PutBucketLogging | PUT /{bucket}?logging | handleBucketLogging | saveBucketMetadata | |
| GetPublicAccessBlock | GET /{bucket}?publicAccessBlock | handlePublicAccessBlock | getPublicAccessBlock | |
| PutPublicAccessBlock | PUT /{bucket}?publicAccessBlock | handlePublicAccessBlock | setPublicAccessBlock | |
| DeletePublicAccessBlock | DELETE /{bucket}?publicAccessBlock | handlePublicAccessBlock | setPublicAccessBlock (clear) | |
| GetObjectLockConfiguration | GET /{bucket}?object-lock | handleObjectLockConfiguration | getObjectLockConfiguration | |
| PutObjectLockConfiguration | PUT /{bucket}?object-lock | handleObjectLockConfiguration | setObjectLockConfiguration | |
| GetBucketOwnershipControls | GET /{bucket}?ownershipControls | handleOwnershipControls | getBucketOwnershipControls | |
| PutBucketOwnershipControls | PUT /{bucket}?ownershipControls | handleOwnershipControls | setBucketOwnershipControls | |
| DeleteBucketOwnershipControls | DELETE /{bucket}?ownershipControls | handleOwnershipControls | setBucketOwnershipControls (clear) |
Object CRUD — ObjectHandler and delegates
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| PutObject | PUT /{bucket}/{key} | PutObjectHandler.handlePutObject | handlePutObject | No x-amz-copy-source header |
| CopyObject | PUT /{bucket}/{key} + x-amz-copy-source | CopyObjectHandler.handleCopyObject | handlePutObject / copy path | Header selects copy |
| GetObject | GET /{bucket}/{key} | GetObjectHandler.handleGetObject | getObject / tryFastGetObject | Ranges, conditionals, SSE-C; plain GET may take the event-loop fast path in S3Handler.tryFastGet |
| HeadObject | HEAD /{bucket}/{key} | GetObjectHandler.handleHeadObject | getObjectMetadata | |
| DeleteObject | DELETE /{bucket}/{key} | ObjectHandler.handleDeleteObject | handleDeleteObjectVersioned | Conditional headers, governance bypass |
Object sub-resources — ObjectSubresourceHandler
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| GetObjectTagging | GET /{bucket}/{key}?tagging | handleObjectTagging | getObjectTags | |
| PutObjectTagging | PUT /{bucket}/{key}?tagging | handleObjectTagging | putObjectTags | |
| DeleteObjectTagging | DELETE /{bucket}/{key}?tagging | handleObjectTagging | deleteObjectTags | |
| GetObjectAcl | GET /{bucket}/{key}?acl | handleObjectAcl | getObjectMetadata | |
| PutObjectAcl | PUT /{bucket}/{key}?acl | handleObjectAcl | setObjectAcl, setObjectAclGrants | Refused under BucketOwnerEnforced |
| GetObjectLegalHold | GET /{bucket}/{key}?legal-hold | handleObjectLegalHold | getObjectLegalHold | Object-lock must be enabled |
| PutObjectLegalHold | PUT /{bucket}/{key}?legal-hold | handleObjectLegalHold | setObjectLegalHold | |
| GetObjectRetention | GET /{bucket}/{key}?retention | handleObjectRetention | getObjectRetention | |
| PutObjectRetention | PUT /{bucket}/{key}?retention | handleObjectRetention | setObjectRetention | Weakening needs governance bypass |
| GetObjectAttributes | GET /{bucket}/{key}?attributes | handleGetObjectAttributes | getObjectMetadata, getVersionedObjectMetadata | |
| RestoreObject | POST /{bucket}/{key}?restore | handlePostRestoreObject | — | No real archival tier; immediate restore |
| GetObjectTorrent | GET /{bucket}/{key}?torrent | handleGetObjectTorrent | — | Legacy; returns 404 NoSuchKey |
Multipart — MultipartHandler
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| CreateMultipartUpload | POST /{bucket}/{key}?uploads | handleMultipartUpload | MultipartStore init | Non-GET with uploads and no uploadId |
| ListMultipartUploads | GET /{bucket}?uploads | handleListMultipartUploads | MultipartStore list | GET with uploads |
| UploadPart | PUT /{bucket}/{key}?uploadId&partNumber | handleUploadPart | handleUploadPart / handleUploadPartChannel | |
| UploadPartCopy | PUT /{bucket}/{key}?uploadId&partNumber + x-amz-copy-source | handleUploadPartCopy | handleUploadPartChannel | Header selects copy |
| CompleteMultipartUpload | POST /{bucket}/{key}?uploadId | handleCompleteMultipartUpload | complete/assemble | Retry-idempotent via completed-upload cache |
| AbortMultipartUpload | DELETE /{bucket}/{key}?uploadId | handleAbortMultipartUpload | handleAbortMultipartUpload | |
| ListParts | GET /{bucket}/{key}?uploadId | handleListParts | MultipartStore list parts |
Bulk delete — DeleteObjectsPostHandler
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| DeleteObjects | POST /{bucket}?delete | DeleteObjectsPostHandler.handleDeleteObjects | handleDeleteObjectVersioned (per key) | Dispatched from BucketHandler.handleBucketOperation |
POST form upload — BucketUploadPostHandler
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| PostObject (browser form POST) | POST /{bucket} (multipart/form-data) | BucketUploadPostHandler.handle | handlePutObject | Detected via S3Context.isPostBucketUpload; POST policy signature. Documented as PutObject in the reference. |
S3 Select — SelectObjectContentHandler
| Operation | HTTP (verb + path/query) | Handler class | Facade method | Notes |
|---|---|---|---|---|
| SelectObjectContent | POST /{bucket}/{key}?select&select-type=2 | SelectObjectContentHandler.handleSelectObjectContent | getObject (source read) | Query engine: DefaultSelectQueryEngine |