Documentation
¶
Overview ¶
An S3 compatible server that only implements what's actually needed for cling-sync clients. It only ever serves one repository.
S3-protocol Storage. Speaks to any S3-compatible service via HTTPClient so the same client works under net/http (CLI) and js/fetch (wasm).
S3 URI encoding and decoding of the form:
s3+https://<base64url(argon2id-phc)>:<base64url(ciphertext)>@<host>[/<prefix>]
AWS Signature V4 request signing. https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
Signing is wasm-safe and used by the S3 client. Verification lives in sigv4verify.go so that the net/http dependency it needs gets excluded from wasm builds.
Index ¶
- func CORSMiddleware(next http.Handler) http.Handler
- func EncodeS3URI(rawURL string, creds S3Credentials, passphrase []byte) (string, error)
- func IsS3StorageURI(uri string) bool
- func RejectBareHTTPURI(uri string) error
- func RequestLogMiddleware(handler http.Handler) http.Handler
- func S3URIHasEmbeddedCredentials(uri string) bool
- func VerifySigV4(req *http.Request, body []byte, region string, ...) error
- type DefaultHTTPClient
- type HTTPClient
- type S3Credentials
- type S3StorageClient
- func (c *S3StorageClient) DeleteControlFile(ctx context.Context, section lib.ControlFileSection, name string) error
- func (c *S3StorageClient) ForceUnlock(ctx context.Context, name string) error
- func (c *S3StorageClient) HasBlock(ctx context.Context, blockId lib.BlockId) (bool, error)
- func (c *S3StorageClient) HasControlFile(ctx context.Context, section lib.ControlFileSection, name string) (bool, error)
- func (c *S3StorageClient) Init(ctx context.Context, config lib.Toml, headerComment string) error
- func (c *S3StorageClient) Lock(ctx context.Context, name string) (func() error, error)
- func (c *S3StorageClient) Open(ctx context.Context) (lib.Toml, error)
- func (c *S3StorageClient) ReadBlock(ctx context.Context, blockId lib.BlockId, buf lib.BlockBuf) ([]byte, error)
- func (c *S3StorageClient) ReadBlockIds(ctx context.Context, yield func(lib.BlockId) bool) error
- func (c *S3StorageClient) ReadControlFile(ctx context.Context, section lib.ControlFileSection, name string) ([]byte, error)
- func (c *S3StorageClient) WriteBlock(ctx context.Context, blockId lib.BlockId, data []byte) (bool, error)
- func (c *S3StorageClient) WriteControlFile(ctx context.Context, section lib.ControlFileSection, name string, data []byte) error
- type S3StorageConfig
- type S3StorageServer
- type SigV4Signer
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EncodeS3URI ¶
func EncodeS3URI(rawURL string, creds S3Credentials, passphrase []byte) (string, error)
func IsS3StorageURI ¶
func RejectBareHTTPURI ¶
RejectBareHTTPURI returns an error when `uri` is a plain `http://` or `https://` URL.
func S3URIHasEmbeddedCredentials ¶
S3URIHasEmbeddedCredentials reports whether the URI already carries an encrypted credentials blob in its userinfo (as produced by EncodeS3URI).
func VerifySigV4 ¶
func VerifySigV4( req *http.Request, body []byte, region string, accessKeyID, secretAccessKey string, now time.Time, ) error
VerifySigV4 re-signs the request with `secretAccessKey` and compares to the Authorization header. The header's access key must equal `accessKeyID`. `now` is the server's clock for the ±15-minute skew window check.
Types ¶
type DefaultHTTPClient ¶
func NewDefaultHTTPClient ¶
func NewDefaultHTTPClient(client *http.Client) *DefaultHTTPClient
NewDefaultHTTPClient wraps `client`. A nil `client` gets a transport with per-phase timeouts (dial 30s, TLS handshake 10s, response headers 60s) so a dead connection cannot hang a request forever. `http.Client.Timeout` is deliberately left at zero: it would also cap the body transfer and cut off slow but flowing block reads. A transfer that stalls mid-body is only caught by cancelling the request context.
type HTTPClient ¶
type S3Credentials ¶
type S3StorageClient ¶
type S3StorageClient struct {
// contains filtered or unexported fields
}
func NewS3StorageClient ¶
func NewS3StorageClient(cfg S3StorageConfig, httpClient HTTPClient) *S3StorageClient
func (*S3StorageClient) DeleteControlFile ¶
func (c *S3StorageClient) DeleteControlFile(ctx context.Context, section lib.ControlFileSection, name string) error
func (*S3StorageClient) ForceUnlock ¶
func (c *S3StorageClient) ForceUnlock(ctx context.Context, name string) error
func (*S3StorageClient) HasControlFile ¶
func (c *S3StorageClient) HasControlFile( ctx context.Context, section lib.ControlFileSection, name string, ) (bool, error)
func (*S3StorageClient) ReadBlockIds ¶
func (*S3StorageClient) ReadControlFile ¶
func (c *S3StorageClient) ReadControlFile( ctx context.Context, section lib.ControlFileSection, name string, ) ([]byte, error)
func (*S3StorageClient) WriteBlock ¶
func (*S3StorageClient) WriteControlFile ¶
func (c *S3StorageClient) WriteControlFile( ctx context.Context, section lib.ControlFileSection, name string, data []byte, ) error
type S3StorageConfig ¶
type S3StorageConfig struct {
BucketURL string
Region string
Prefix string
AccessKeyID string
SecretAccessKey []byte
}
func DecodeS3URI ¶
func DecodeS3URI(uri string, passphrase []byte) (S3StorageConfig, string, error)
func ParseS3Endpoint ¶
func ParseS3Endpoint(endpoint string, creds S3Credentials) (S3StorageConfig, error)
type S3StorageServer ¶
type S3StorageServer struct {
Storage lib.Storage
Region string
AccessKeyID string
SecretAccessKey string
ListPageSize int
ListInactivityTimeout time.Duration
// contains filtered or unexported fields
}
func NewS3StorageServer ¶
func NewS3StorageServer(storage lib.Storage, region, accessKeyID, secretAccessKey string) *S3StorageServer
func (*S3StorageServer) RegisterRoutes ¶
func (s *S3StorageServer) RegisterRoutes(mux *http.ServeMux)
func (*S3StorageServer) ServeHTTP ¶
func (s *S3StorageServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
type SigV4Signer ¶
func (SigV4Signer) Sign ¶
func (s SigV4Signer) Sign(method, fullURL string, headers map[string]string, body []byte, now time.Time) error
Sign adds X-Amz-Date, X-Amz-Content-Sha256, and Authorization entries to `headers`. `fullURL` is used only to extract host, path, and query for the canonical request.