The Bucket methods, their Go options and what they return. Each section links to the concept page with the behaviour and defaults.
Building the client is on Overview. Every method takes a context.Context first. Options come as a pointer to a struct; pass nil for none.
Put#
Every field is optional. Behaviour and defaults are on Writing.
| Field | Type | Description |
|---|---|---|
ContentType | string | What the object is stored as. |
ContentTypes | []string | An allow list such as []string{"image/*", "application/pdf"}. A non-nil empty slice is refused with invalid_content_type_pattern. See Constraints. |
MaxSize | int64 | Refuses a larger body with too_large. Zero is no limit. |
Cache | string | The Cache-Control this object is stored with. See Caching. |
Metadata | map[string]string | Custom key-value pairs. A key with an uppercase letter is refused with invalid_input rather than lowercased for you. See Metadata. |
Size | int64 | The exact length in bytes, for a reader whose length is not otherwise known. Ignored for a body Put can measure. |
NoOverwrite | bool | Refuses the write if something is already at the path. See Conditional writes. |
IfUnchanged | string | An etag. The write fails with conflict if the object changed since you read it. |
Multipart | blob.Multipart | Where a body stops being one PUT. See Large bodies. |
The result is a *CompletedBlob:
Bodies#
The body is any io.Reader. What Put can learn from it decides whether it needs a declared size, and whether a failed request can be sent again:
| Body | Carries its length | Carries a content type | Retried |
|---|---|---|---|
*bytes.Reader, *strings.Reader, *bytes.Buffer | Yes | No | Yes |
A regular *os.File | Yes: what is left from its offset | From its extension | Yes |
Any other io.ReaderAt that is also an io.Seeker, such as a multipart.File, but not a non-regular file | Yes: what is left from its offset | No | Yes |
Any other io.Seeker | Yes | No | No, sent once |
Any other io.Reader, such as a request body, os.Stdin, a pipe or a gzip.Reader | No: declare Size or MaxSize | No | Under MaxSize yes; under Size no |
nil | Zero bytes | No | Yes |
The Retried column is for a single PUT. A body over the multipart threshold goes up in parts, each buffered and retried on its own, whatever the body type, unless the write is conditional.
An explicit ContentType wins over the extension. Without either, the object is stored as application/octet-stream.
Putnever closes the body.- A
*bytes.Bufferis read in place, not drained. - There is no request body type, so
Putnever returnsempty_body. A zero-length body stores a zero-byte object.
Request bodies#
A multipart.File from r.FormFile is measured and read in place. Pass the content type from the form part’s header: a multipart.File has no name for Put to read one from.
A raw request body has no length Put can read. Pass r.ContentLength as Size only when it is known; a chunked request reports -1, which is refused:
The bytes pass through your server here, under your platform’s body limit. For anything large, use an upload handler instead. writeError is on Errors.
Streams#
A reader with neither fails with length_required. Why is on Streams and unknown lengths. One that ends short of Size, or runs past it, fails with invalid_input.
res.ContentLength is -1 when the length is unknown: a chunked response, or one Go’s transport decompressed for you. A negative Size is refused with invalid_input and a zero one counts as unset, so check it first, or fall back to MaxSize.
UniquePath#
A package function. The suffix rules are on Unique paths.
UpdateJSON#
| Field | Type | Description |
|---|---|---|
MaxAttempts | int | How many read-transform-write rounds to try before failing with conflict. Zero is 6; a negative count is invalid_input. |
Cache | string | The Cache-Control the rewritten object is stored with. |
Metadata | map[string]string | Replaces the metadata on the object. Nil keeps it. |
A package function rather than a method, since Go methods cannot take a type parameter. The document is decoded into a T with encoding/json, and the result encoded the same way. fn gets nil when nothing is stored, the object is empty, or it holds JSON null. An error from fn is returned as is, with nothing written. A stored document that is not JSON fails with invalid_input.
The loop and its defaults are on Updating JSON.
Copy and Move#
| Field | Type | Description |
|---|---|---|
ContentType | string | What the destination is stored as. |
Cache | string | The Cache-Control the destination is stored with. |
Metadata | map[string]string | Replaces the metadata outright. Nil keeps the source’s; an empty non-nil map stores none. |
What carries over from the source is on copy and move. A move onto its own path only applies the options.
SignedUploadURL#
Returns a *SignedUploadURL with URL string, Headers map[string]string and ExpiresAt time.Time. Send Headers verbatim, except that net/http takes the length from Request.ContentLength, not from a header: a *bytes.Reader body sets it for you, and an *os.File body does not.
| Field | Type | Description |
|---|---|---|
ExpiresIn | time.Duration | How long the link should live. Zero is the default. |
ContentType | string | The Content-Type the upload must send, and what the object is stored as. |
Cache | string | The Cache-Control the object is stored with. |
Metadata | map[string]string | Written as x-amz-meta-*, under the same rules as Put. |
Size | int64 | Pins the body’s exact length. Zero leaves it open. |
NoOverwrite | bool | Refuses the upload if something is already at the path. |
Defaults and lifetimes are on Signed upload URLs.
Get#
Body is the response stream: nothing is buffered, and you must close it. io.ReadAll(res.Body) reads it in full.
A missing object fails with not_found. It never returns a nil download with a nil error. See get.
Info and Exists#
List#
Returns a *ListPage with Blobs []BlobObject and Cursor string, which is "" on the last page.
| Field | Type | Description |
|---|---|---|
Prefix | string | Only keys starting with this. |
Limit | int | Page size. Zero lets storage pick. |
Cursor | string | The Cursor from the previous page. |
Defaults and paging are on list.
PublicURL#
"" on a private bucket. An empty path, or one with a . or .. segment, is refused with invalid_input. It takes a context because the first call fetches credentials. See Public URLs.
SignedReadURL#
Returns a *SignedURL with URL string and ExpiresAt time.Time. Cache the link until ExpiresAt, never until a deadline you compute from ExpiresIn.
| Field | Type | Description |
|---|---|---|
ExpiresIn | time.Duration | How long to ask for. Zero is the default. |
DownloadAs | string | Save as this filename instead of displaying inline. |
ContentType | string | What storage answers with as Content-Type, overriding what was stored. |
Defaults and lifetimes are on Signed read URLs.
Delete#
Each shape is its own method. DeletePrefix("") is refused with invalid_input; DeleteAll is how to say you mean it. DeleteMany checks every path before the first request, so a bad path deletes nothing. What each shape does and returns is on Deleting.
Multipart cleanup#
MultipartUpload is a struct with Path string, UploadID string and InitiatedAt time.Time. Pass "" as the prefix for the whole bucket.
AbortMultipartUpload takes the record, not two strings, because a swapped pair would abort nothing and report success. An empty UploadID is refused with invalid_input. To abort an upload whose id you stored from an upload handler, build the record:
olderThan is the window from Aborting stale uploads. Zero aborts every incomplete upload under the prefix, including ones still running. If an abort fails partway, the uploads already aborted are returned along with the error.
S3#
Short-lived credentials for the AWS SDK or any S3 client. See Using an S3 client.
Records#
Records are structs. They nest by embedding, so a *CompletedBlob has every BlobObject field directly. What each field means is on Records.
| Type | Fields | Returned by |
|---|---|---|
BlobObject | Path, URL, VersionedURL, Size, ETag, UploadedAt | List, Copy, Move, UpdateJSON |
CompletedBlob | BlobObject plus ContentType | Put, OnUploadComplete |
BlobInfo | BlobObject plus ContentType and Metadata | Info |
BlobDownload | BlobInfo plus Body io.ReadCloser | Get |
| Field | Type |
|---|---|
Path | string |
URL | string, "" on a private bucket |
VersionedURL | string, "" when URL is |
Size | int64 |
ETag | string |
UploadedAt | time.Time |
ContentType | string |
Metadata | map[string]string |
Records encode to JSON with the field names the TypeScript SDK uses (path, url, versionedUrl, uploadedAt, …), so one can be returned from your own route as is.