From 4b8eac2689d87534a0beef8343efd28b151a8bf9 Mon Sep 17 00:00:00 2001 From: Pradeep Sharma Date: Thu, 22 Oct 2026 10:59:39 -0700 Subject: [PATCH] OCI: returned URLs have an unexpanded endpoint template in the host On an OCI store with no endpoint configured, the location returned by UploadFile and the link returned by PresignedURL had a host such as objectstorage.us-chicago-1.{dualStack?ds.oci.:}oraclecloud.com, so they could not be fetched. Uploads and other object operations were unaffected. oci-go-sdk v65.126.1 adds the {dualStack?...} option to the Object Storage endpoint template and fills it in per request on a copy of the client, so client.Host keeps the raw template. NewOCI now fills in the endpoint options with common.UpdateEndpointTemplateForOptions on a copy before saving the host. Co-Authored-By: Claude Opus 5.5 --- oci.go | 8 +++++--- oci_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/oci.go b/oci.go index 4ee95a4..77508ff 100644 --- a/oci.go +++ b/oci.go @@ -81,9 +81,11 @@ func NewOCI(conf *OCIConfig) (Storage, error) { client.HTTPClient = c } - // The SDK only prepends a scheme to client.Host on the first request, so - // read it before GetNamespace below. - host := strings.TrimPrefix(client.Host, "https://") + // client.Host keeps endpoint options such as {dualStack?ds.oci.:}, which the + // SDK resolves on a copy per request, so resolve them the same way here. + resolved := client.BaseClient + common.UpdateEndpointTemplateForOptions(&resolved) + host := strings.TrimPrefix(resolved.Host, "https://") insecure := strings.HasPrefix(host, "http://") host = strings.TrimPrefix(host, "http://") diff --git a/oci_test.go b/oci_test.go index b08b427..0d3d4c6 100644 --- a/oci_test.go +++ b/oci_test.go @@ -15,6 +15,11 @@ package storage import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "net/url" "testing" "github.com/stretchr/testify/require" @@ -63,3 +68,25 @@ func TestNewConfigProvider(t *testing.T) { require.NotNil(t, provider) }) } + +func TestOCILocationHost(t *testing.T) { + key, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + pemKey := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}) + + // A set Namespace keeps NewOCI off the network. + s, err := NewOCI(&OCIConfig{ + TenancyOCID: "ocid1.tenancy.oc1..tenancy", + UserOCID: "ocid1.user.oc1..user", + Fingerprint: "aa:bb:cc", + PrivateKey: string(pemKey), + Region: "us-chicago-1", + Namespace: "ns", + Bucket: "bucket", + }) + require.NoError(t, err) + + u, err := url.Parse(s.(*ociStorage).location("a/b.mp4")) + require.NoError(t, err) + require.Equal(t, "objectstorage.us-chicago-1.oraclecloud.com", u.Host) +}