http

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: MIT Imports: 24 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func CORSMiddleware

func CORSMiddleware(next http.Handler) http.Handler

func EncodeS3URI

func EncodeS3URI(rawURL string, creds S3Credentials, passphrase []byte) (string, error)

func IsS3StorageURI

func IsS3StorageURI(uri string) bool

func RejectBareHTTPURI

func RejectBareHTTPURI(uri string) error

RejectBareHTTPURI returns an error when `uri` is a plain `http://` or `https://` URL.

func RequestLogMiddleware

func RequestLogMiddleware(handler http.Handler) http.Handler

func S3URIHasEmbeddedCredentials

func S3URIHasEmbeddedCredentials(uri string) bool

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

type DefaultHTTPClient struct {
	Client *http.Client
}

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.

func (*DefaultHTTPClient) Request

func (c *DefaultHTTPClient) Request(
	ctx context.Context,
	method, fullURL string,
	headers map[string]string,
	body, dst []byte,
) (int, []byte, error)

type HTTPClient

type HTTPClient interface {
	// Response bytes go into `dst` when non-nil, otherwise into a fresh slice capped at `MaxBlockSize`.
	Request(
		ctx context.Context,
		method, url string,
		headers map[string]string,
		body, dst []byte,
	) (status int, respBody []byte, err error)
}

type S3Credentials

type S3Credentials struct {
	AccessKeyID     string
	SecretAccessKey []byte
}

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) HasBlock

func (c *S3StorageClient) HasBlock(ctx context.Context, blockId lib.BlockId) (bool, error)

func (*S3StorageClient) HasControlFile

func (c *S3StorageClient) HasControlFile(
	ctx context.Context,
	section lib.ControlFileSection,
	name string,
) (bool, error)

func (*S3StorageClient) Init

func (c *S3StorageClient) Init(ctx context.Context, config lib.Toml, headerComment string) error

func (*S3StorageClient) Lock

func (c *S3StorageClient) Lock(ctx context.Context, name string) (func() error, error)

func (*S3StorageClient) Open

func (c *S3StorageClient) Open(ctx context.Context) (lib.Toml, error)

func (*S3StorageClient) ReadBlock

func (c *S3StorageClient) ReadBlock(ctx context.Context, blockId lib.BlockId, buf lib.BlockBuf) ([]byte, error)

func (*S3StorageClient) ReadBlockIds

func (c *S3StorageClient) ReadBlockIds(ctx context.Context, yield func(lib.BlockId) bool) error

func (*S3StorageClient) ReadControlFile

func (c *S3StorageClient) ReadControlFile(
	ctx context.Context,
	section lib.ControlFileSection,
	name string,
) ([]byte, error)

func (*S3StorageClient) WriteBlock

func (c *S3StorageClient) WriteBlock(ctx context.Context, blockId lib.BlockId, data []byte) (bool, error)

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

type SigV4Signer struct {
	AccessKeyID     string
	SecretAccessKey string
	Region          string
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL