Documentation
¶
Overview ¶
Package s3 is an S3 client that builds with TinyGo.
The maintained Go clients cannot be used here. aws-sdk-go-v2 reaches for the full net/http.Transport API, which TinyGo declares as an empty struct, and its transport layer imports net/http/httputil, which does not compile under TinyGo at all. This package therefore speaks the S3 REST API directly: a SigV4 signer, request builders, and XML decoding, over whichever HTTP stack the build selects.
client, err := s3.New(
s3.WithRegion("ap-northeast-1"),
s3.WithCredentials(s3.Credentials{AccessKeyID: id, SecretAccessKey: secret}),
)
obj, err := client.Get(ctx, "bucket", "photos/cat.jpg")
defer obj.Body.Close()
Implementation selection ¶
Signing, request building, and response decoding are shared code: the two builds differ only in how a request reaches the network.
- standard Go builds use net/http and crypto/tls
- TinyGo builds use github.com/shibukawa/tinygodriver/https, which performs TLS through the TLS stack of the host OS
- go build -tags force_tinygo_logic selects the TinyGo path under host Go, which is how that path is tested without a TinyGo toolchain
Neither build follows redirects through http.Client, because a redirected request must be signed again for its new host. Redirects are handled here instead, so a bucket in another region works the same way on both builds.
Credentials ¶
Credentials are static values or environment variables. There is no shared credentials file, no SSO, and no IMDS lookup:
s3.WithCredentials(s3.Credentials{AccessKeyID: id, SecretAccessKey: secret})
s3.WithCredentialsFromEnv() // AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, ...
New reads the environment when no credentials option is given.
Scope ¶
Whole-object operations only. Multipart upload is not implemented, so Put sends one request and is bounded by what the endpoint accepts in a single PUT (5 GiB on AWS). Large uploads should use a stream the package can rewind or hash, see Put.
Index ¶
- Constants
- Variables
- type Client
- func (c *Client) CreateBucket(ctx context.Context, bucket string) error
- func (c *Client) Delete(ctx context.Context, bucket, key string) error
- func (c *Client) DeleteBucket(ctx context.Context, bucket string) error
- func (c *Client) Endpoint() string
- func (c *Client) Get(ctx context.Context, bucket, key string) (*Object, error)
- func (c *Client) GetRange(ctx context.Context, bucket, key string, offset, length int64) (*Object, error)
- func (c *Client) Head(ctx context.Context, bucket, key string) (*ObjectInfo, error)
- func (c *Client) List(ctx context.Context, bucket string, opts ...ListOption) (*ListResult, error)
- func (c *Client) Put(ctx context.Context, bucket, key string, body io.Reader, opts ...PutOption) (*PutResult, error)
- func (c *Client) Region() string
- type Credentials
- type Error
- type ListOption
- type ListResult
- type Object
- type ObjectInfo
- type Option
- func WithCredentials(creds Credentials) Option
- func WithCredentialsFromEnv() Option
- func WithEndpoint(endpoint string) Option
- func WithHTTPClient(client *http.Client) Option
- func WithPathStyle(pathStyle bool) Option
- func WithRegion(region string) Option
- func WithTimeout(timeout time.Duration) Option
- func WithUnsignedPayload(unsigned bool) Option
- type PutOption
- type PutResult
Constants ¶
const Backend = aws.Backend
Backend identifies the HTTP stack selected by build constraints: "net/http" on standard Go builds, "https" on TinyGo builds.
const DefaultTimeout = 60 * time.Second
DefaultTimeout bounds one logical operation when no timeout is configured.
Variables ¶
var ( ErrNoSuchKey = errors.New("s3: no such key") ErrNoSuchBucket = errors.New("s3: no such bucket") ErrAccessDenied = errors.New("s3: access denied") ErrBucketExists = errors.New("s3: bucket already exists") ErrBucketNotEmpty = errors.New("s3: bucket not empty") ErrInvalidRange = errors.New("s3: requested range not satisfiable") ErrBadCredentials = errors.New("s3: credentials rejected") // Configuration failures are the shared ones, so errors.Is matches whether // the caller compares against s3 or cloud/aws. ErrNoCredentials = aws.ErrNoCredentials ErrNoRegion = aws.ErrNoRegion ErrTooManyRedirect = errors.New("s3: too many redirects") )
Sentinel errors. S3 error codes are mapped onto them so application code can branch with errors.Is without matching strings.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to one S3 endpoint. It is safe for concurrent use.
func New ¶
New builds a Client. Region, endpoint, and credentials fall back to the environment, so a configured shell needs no options at all.
func (*Client) CreateBucket ¶
CreateBucket creates a bucket in the client's region. A bucket that already belongs to the caller reports ErrBucketExists.
func (*Client) Delete ¶
Delete removes an object. Deleting a key that does not exist succeeds, which is how S3 itself behaves.
func (*Client) DeleteBucket ¶
DeleteBucket removes an empty bucket.
func (*Client) GetRange ¶
func (c *Client) GetRange(ctx context.Context, bucket, key string, offset, length int64) (*Object, error)
GetRange retrieves length bytes starting at offset. A length of zero or less reads to the end of the object.
func (*Client) List ¶
func (c *Client) List(ctx context.Context, bucket string, opts ...ListOption) (*ListResult, error)
List returns one page of a bucket listing. A truncated page carries NextToken, which WithContinuationToken feeds back to fetch the next one.
func (*Client) Put ¶
func (c *Client) Put(ctx context.Context, bucket, key string, body io.Reader, opts ...PutOption) (*PutResult, error)
Put stores body under key.
There is no multipart upload, so the whole object is sent in one request and the endpoint's single-request limit applies (5 GiB on AWS).
SigV4 signs a hash of the body, so the body must be read twice. A body that implements io.Seeker (an *os.File, a *bytes.Reader) is hashed and rewound; anything else is buffered in memory. Configure WithUnsignedPayload to stream instead, at the cost of the signature no longer covering the body.
type Credentials ¶
type Credentials = aws.Credentials
Credentials are the values SigV4 signs with. It is an alias, so credentials built here work with any other client in this repository.
func CredentialsFromEnv ¶
func CredentialsFromEnv() Credentials
CredentialsFromEnv reads AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN.
type Error ¶
type Error struct {
Op string // "Get", "Put", "List", ...
Bucket string
Key string
StatusCode int
Code string
Message string
RequestID string
// contains filtered or unexported fields
}
Error is a failed S3 operation. Code and Message come from the XML error document when the endpoint sent one.
type ListOption ¶
type ListOption func(*listConfig)
ListOption configures a single List call.
func WithContinuationToken ¶
func WithContinuationToken(token string) ListOption
WithContinuationToken resumes a truncated listing from ListResult.NextToken.
func WithDelimiter ¶
func WithDelimiter(delimiter string) ListOption
WithDelimiter groups keys sharing a prefix up to the delimiter, reporting them in ListResult.CommonPrefixes. Use "/" to walk a listing like a directory tree.
func WithMaxKeys ¶
func WithMaxKeys(maxKeys int) ListOption
WithMaxKeys caps how many keys one page returns.
func WithPrefix ¶
func WithPrefix(prefix string) ListOption
WithPrefix limits the listing to keys with this prefix.
func WithStartAfter ¶
func WithStartAfter(key string) ListOption
WithStartAfter begins the listing after this key.
type ListResult ¶
type ListResult struct {
Objects []ObjectInfo
CommonPrefixes []string
IsTruncated bool
// NextToken continues a truncated listing through WithContinuationToken.
NextToken string
}
ListResult is one page of a listing.
type Object ¶
type Object struct {
ObjectInfo
Body io.ReadCloser
}
Object is an object body together with its metadata. Body must be closed.
type ObjectInfo ¶
type ObjectInfo struct {
Key string
Size int64
ETag string
ContentType string
ContentEncoding string
LastModified time.Time
// Metadata holds user metadata, with the x-amz-meta- prefix removed.
Metadata map[string]string
}
ObjectInfo is the metadata S3 reports for an object.
type Option ¶
type Option func(*config)
Option configures a Client.
func WithCredentials ¶
func WithCredentials(creds Credentials) Option
WithCredentials sets static credentials.
func WithCredentialsFromEnv ¶
func WithCredentialsFromEnv() Option
WithCredentialsFromEnv reads credentials from the environment. New does this already when no credentials option is given; the option states it explicitly.
func WithEndpoint ¶
WithEndpoint overrides the endpoint URL, for S3-compatible servers such as RustFS or MinIO. It defaults to AWS_ENDPOINT_URL_S3, AWS_ENDPOINT_URL, or the regional AWS endpoint.
func WithHTTPClient ¶
WithHTTPClient supplies the http.Client to use.
Its CheckRedirect must return http.ErrUseLastResponse on standard Go builds: a redirected request has to be signed again for its new host, which this package does itself.
func WithPathStyle ¶
WithPathStyle selects between https://endpoint/bucket/key and https://bucket.endpoint/key addressing.
The default is virtual-host addressing for amazonaws.com endpoints and path addressing everywhere else, which is what S3-compatible servers expect.
func WithRegion ¶
WithRegion sets the signing region. It defaults to AWS_REGION, then AWS_DEFAULT_REGION.
func WithTimeout ¶
WithTimeout bounds one logical operation, including redirects and reading the response body. Zero means DefaultTimeout.
func WithUnsignedPayload ¶
WithUnsignedPayload signs requests with UNSIGNED-PAYLOAD instead of the body hash, so Put streams a body it cannot rewind instead of buffering it.
The request headers stay signed. Use it only over https, where TLS protects the body that the signature no longer covers.
type PutOption ¶
type PutOption func(*putConfig)
PutOption configures a single Put.
func WithContentEncoding ¶
WithContentEncoding sets the object's Content-Encoding, for a body that is already compressed.
func WithContentLength ¶
WithContentLength states the body size for a stream the package cannot measure, which matters together with WithUnsignedPayload: without a length, the body goes out chunked, and AWS rejects a chunked PutObject.
func WithContentType ¶
WithContentType sets the object's Content-Type.
func WithMetadata ¶
WithMetadata attaches user metadata, sent as x-amz-meta-* headers.