package objects import ( "context" "errors" "fmt" "net/http" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/vaughan0/go-ini" ) var s3CtxKey = &contextKey{"s3"} type contextKey struct { name string } func Middleware(client *s3.Client) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx := Context(r.Context(), client) r = r.WithContext(ctx) next.ServeHTTP(w, r) }) } } func Context(ctx context.Context, client *s3.Client) context.Context { return context.WithValue(ctx, s3CtxKey, client) } func ForContext(ctx context.Context) *s3.Client { raw, ok := ctx.Value(s3CtxKey).(*s3.Client) if !ok { panic(fmt.Errorf("Invalid S3 context")) } return raw } var ErrDisabled = errors.New("object storage is not enabled for this server") func NewClient(conf ini.File) (*s3.Client, error) { upstream, _ := conf.Get("objects", "s3-upstream") accessKey, _ := conf.Get("objects", "s3-access-key") secretKey, _ := conf.Get("objects", "s3-secret-key") if upstream == "" || accessKey == "" || secretKey == "" { return nil, ErrDisabled } region, ok := conf.Get("objects", "s3-region") if !ok { region = "default" } creds := credentials.NewStaticCredentialsProvider(accessKey, secretKey, "") return s3.NewFromConfig(aws.Config{ Region: region, Credentials: creds, }, func(opts *s3.Options) { opts.BaseEndpoint = aws.String(upstream) }), nil } func URL(conf ini.File) string { upstream, _ := conf.Get("objects", "s3-upstream") if upstream == "" { return "" } return "https://" + upstream } func Enabled(conf ini.File) bool { upstream, _ := conf.Get("objects", "s3-upstream") accessKey, _ := conf.Get("objects", "s3-access-key") secretKey, _ := conf.Get("objects", "s3-secret-key") return upstream != "" && accessKey != "" && secretKey != "" }