Files
go-omni/storage/oss/read.go

60 lines
2.1 KiB
Go

package oss
import (
"context"
"errors"
"net/url"
"strconv"
"time"
"git.yuntuo.hk/k2safe/go-omni/storage"
sdk "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
)
func (s *Store) PresignGetWithOptions(ctx context.Context, key string, ttl time.Duration, options storage.ReadOptions) (storage.ReadLink, error) {
if err := storage.Check(ctx, key); err != nil {
return storage.ReadLink{}, err
}
if ttl < time.Second || ttl > time.Hour {
return storage.ReadLink{}, errors.New("storage/oss: TTL must be 1s..1h")
}
headers, err := options.ResponseHeaders()
if err != nil {
return storage.ReadLink{}, err
}
request := &sdk.GetObjectRequest{Bucket: sdk.Ptr(s.bucket), Key: sdk.Ptr(key), ResponseContentDisposition: sdk.Ptr(headers.Get("Content-Disposition")), ResponseCacheControl: sdk.Ptr(headers.Get("Cache-Control"))}
if contentType := headers.Get("Content-Type"); contentType != "" {
request.ResponseContentType = sdk.Ptr(contentType)
}
r, err := s.client.Presign(ctx, request, sdk.PresignExpires(ttl))
if err != nil {
return storage.ReadLink{}, err
}
if len(r.SignedHeaders) != 0 {
return storage.ReadLink{}, errors.New("storage/oss: direct GET requires a signature without additional request headers")
}
u, err := url.Parse(r.URL)
if err != nil {
return storage.ReadLink{}, errors.New("storage/oss: invalid signed URL")
}
q := u.Query()
var expires time.Time
if q.Get("x-oss-signature") != "" {
start, e := time.Parse("20060102T150405Z", q.Get("x-oss-date"))
seconds, e2 := strconv.ParseInt(q.Get("x-oss-expires"), 10, 64)
if e != nil || e2 != nil || seconds < 1 || seconds > 3600 {
return storage.ReadLink{}, errors.New("storage/oss: invalid signed expiry")
}
expires = start.Add(time.Duration(seconds) * time.Second)
} else {
seconds, e := strconv.ParseInt(q.Get("Expires"), 10, 64)
if e != nil || q.Get("Signature") == "" {
return storage.ReadLink{}, errors.New("storage/oss: missing signed expiry")
}
expires = time.Unix(seconds, 0).UTC()
}
return storage.ReadLink{URL: r.URL, ExpiresAt: expires}, nil
}
var _ storage.ReadPresigner = (*Store)(nil)