66 "encoding/base64"
77 "fmt"
88 "mime"
9+ "net/url"
910 "regexp"
1011 "strings"
1112
@@ -248,8 +249,14 @@ func (f *binaryFetcher) convertDataURIToBytes(url string) (b []byte, contentType
248249}
249250
250251// Pattern matches: https://{domain}/v1alpha/namespaces/{namespace}/blob-urls/{uid}
252+ // This is a deprecated pattern, we should use the presigned pattern instead.
251253var minioURLPattern = regexp .MustCompile (`https?://[^/]+/v1alpha/namespaces/[^/]+/blob-urls/([^/]+)$` )
252254
255+ // Pattern matches: https://{domain}/v1alpha/blob-urls/{encoded_presigned_url}
256+ // This is the new pattern, we should use this instead of the deprecated pattern.
257+ // The new design totally rely on the presigned URL provided by MinIO, without the need to get object URL from table.
258+ var minioURLPresignedPattern = regexp .MustCompile (`https?://[^/]+/v1alpha/blob-urls/([^/]+)$` )
259+
253260// ArtifactBinaryFetcher fetches binary data from a URL.
254261// If that URL comes from an object uploaded on Instill Artifact,
255262// it uses the blob storage client directly to avoid egress costs.
@@ -269,19 +276,40 @@ func NewArtifactBinaryFetcher(ac artifactpb.ArtifactPrivateServiceClient, fg *mi
269276 }
270277}
271278
272- func (f * artifactBinaryFetcher ) FetchFromURL (ctx context.Context , url string ) (b []byte , contentType string , filename string , err error ) {
273- if strings .HasPrefix (url , "data:" ) {
274- return f .binaryFetcher .convertDataURIToBytes (url )
279+ func (f * artifactBinaryFetcher ) FetchFromURL (ctx context.Context , fileURL string ) (b []byte , contentType string , filename string , err error ) {
280+ if strings .HasPrefix (fileURL , "data:" ) {
281+ return f .binaryFetcher .convertDataURIToBytes (fileURL )
275282 }
276- if matches := minioURLPattern .FindStringSubmatch (url ); matches != nil {
283+ if matches := minioURLPattern .FindStringSubmatch (fileURL ); matches != nil {
277284 if len (matches ) < 2 {
278- err = fmt .Errorf ("invalid blob storage url: %s" , url )
285+ err = fmt .Errorf ("invalid blob storage url: %s" , fileURL )
279286 return
280287 }
281288
282289 return f .fetchFromBlobStorage (ctx , uuid .FromStringOrNil (matches [1 ]))
283290 }
284- return f .binaryFetcher .FetchFromURL (ctx , url )
291+ if matches := minioURLPresignedPattern .FindStringSubmatch (fileURL ); matches != nil {
292+ if len (matches ) < 1 {
293+ err = fmt .Errorf ("invalid blob storage url: %s" , fileURL )
294+ return
295+ }
296+ parsedURL , err := url .Parse (fileURL )
297+ if err != nil {
298+ return nil , "" , "" , err
299+ }
300+ // The presigned URL is encoded in the format:
301+ // scheme://host/v1alpha/blob-urls/base64_encoded_presigned_url
302+ // Here we decode the base64 string to the presigned URL.
303+ base64Decoded , err := base64 .StdEncoding .DecodeString (strings .Split (parsedURL .Path , "/" )[3 ])
304+ if err != nil {
305+ return nil , "" , "" , err
306+ }
307+
308+ // the decoded presigned URL is a self-contained URL that can be used
309+ // to upload or download the object directly.
310+ return f .binaryFetcher .FetchFromURL (ctx , string (base64Decoded ))
311+ }
312+ return f .binaryFetcher .FetchFromURL (ctx , fileURL )
285313}
286314
287315func (f * artifactBinaryFetcher ) fetchFromBlobStorage (ctx context.Context , urlUID uuid.UUID ) (b []byte , contentType string , filename string , err error ) {
0 commit comments