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)