| // Copyright IBM Corp. 2014, 2026 | |
| // SPDX-License-Identifier: BUSL-1.1 | |
| package moduleaddrs | |
| import ( | |
| "fmt" | |
| "net/url" | |
| "strings" | |
| ) | |
| // detectS3 detects strings that seem like schemeless references to | |
| // Amazon S3 and translates them into URLs for the "s3" getter. | |
| func detectS3(src string) (string, bool, error) { | |
| if len(src) == 0 { | |
| return "", false, nil | |
| } | |
| if strings.Contains(src, ".amazonaws.com/") { | |
| parts := strings.Split(src, "/") | |
| if len(parts) < 2 { | |
| return "", false, fmt.Errorf( | |
| "URL is not a valid S3 URL") | |
| } | |
| hostParts := strings.Split(parts[0], ".") | |
| if len(hostParts) == 3 { | |
| return detectS3PathStyle(hostParts[0], parts[1:]) | |
| } else if len(hostParts) == 4 { | |
| return detectS3OldVhostStyle(hostParts[1], hostParts[0], parts[1:]) | |
| } else if len(hostParts) == 5 && hostParts[1] == "s3" { | |
| return detectS3NewVhostStyle(hostParts[2], hostParts[0], parts[1:]) | |
| } else { | |
| return "", false, fmt.Errorf( | |
| "URL is not a valid S3 URL") | |
| } | |
| } | |
| return "", false, nil | |
| } | |
| func detectS3PathStyle(region string, parts []string) (string, bool, error) { | |
| urlStr := fmt.Sprintf("https://%s.amazonaws.com/%s", region, strings.Join(parts, "/")) | |
| url, err := url.Parse(urlStr) | |
| if err != nil { | |
| return "", false, fmt.Errorf("error parsing S3 URL: %s", err) | |
| } | |
| return "s3::" + url.String(), true, nil | |
| } | |
| func detectS3OldVhostStyle(region, bucket string, parts []string) (string, bool, error) { | |
| urlStr := fmt.Sprintf("https://%s.amazonaws.com/%s/%s", region, bucket, strings.Join(parts, "/")) | |
| url, err := url.Parse(urlStr) | |
| if err != nil { | |
| return "", false, fmt.Errorf("error parsing S3 URL: %s", err) | |
| } | |
| return "s3::" + url.String(), true, nil | |
| } | |
| func detectS3NewVhostStyle(region, bucket string, parts []string) (string, bool, error) { | |
| urlStr := fmt.Sprintf("https://s3.%s.amazonaws.com/%s/%s", region, bucket, strings.Join(parts, "/")) | |
| url, err := url.Parse(urlStr) | |
| if err != nil { | |
| return "", false, fmt.Errorf("error parsing S3 URL: %s", err) | |
| } | |
| return "s3::" + url.String(), true, nil | |
| } |