soju/fileupload/s3.go

56 lines
1.4 KiB
Go

package fileupload
import (
"context"
"fmt"
"io"
"net/url"
"strings"
"time"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/aws"
awss3 "github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/google/uuid"
)
type s3 struct {
endpoint string
}
// load implements Uploader.
func (s *s3) load(filename string) (basename string, modTime time.Time, content io.ReadSeekCloser, err error) {
panic("unimplemented")
}
// store implements Uploader.
func (s *s3) store(r io.Reader, username string, mimeType string, basename string, contentLength int64) (outFilename string, err error) {
split := strings.Split(s.endpoint, "/")
bucket := split[len(split)-1]
filename := url.PathEscape(username) + "/" + uuid.NewString()
endpointResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
URL: s.endpoint,
}, nil
})
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithEndpointResolverWithOptions(endpointResolver),
config.WithRegion("auto"),
)
s3client := awss3.NewFromConfig(cfg)
_, err = s3client.PutObject(context.TODO(), &awss3.PutObjectInput{
Bucket: &bucket,
Key: &filename,
ContentType: &mimeType,
ContentLength: &contentLength,
Body: r,
})
if err != nil {
return "", fmt.Errorf("failed to upload to s3 api: %v", err)
}
return filename, nil
}