Hi @hakoptak
We had a configurational bug in portion of our deployment which is now fixed and this error should not persist anymore.
re: custom cname flavored mp-presigned url in Go can you try with this code once
package main
import (
"bytes"
"context"
"fmt"
"log"
"math/rand"
"net/http"
"strings"
"time"
"github.com/aws/aws-sdk-go-v2/config"
credentials2 "github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/aws/aws-sdk-go/aws"
)
func main_disabled() {
bucket := "<your-bucket-name>"
key := "mp3"
numParts := 3 // how many parts you're uploading
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(
context.TODO(),
config.WithRegion("auto"),
config.WithCredentialsProvider(credentials2.NewStaticCredentialsProvider("tid_<>", "tsec_<>", "")),
)
if err != nil {
log.Fatalf("unable to load SDK config, %v", err)
}
cfg.BaseEndpoint = aws.String("<your custom domain>") // for example https://jmj-test.tigrisdata.cloud
s3Client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true
})
// Step 1: Initiate multipart upload
initOutput, err := s3Client.CreateMultipartUpload(ctx, &s3.CreateMultipartUploadInput{
Bucket: &bucket,
Key: &key,
})
if err != nil {
log.Fatalf("failed to initiate multipart upload: %v", err)
}
uploadID := initOutput.UploadId
fmt.Printf("UploadID: %s\n", uploadID)
// Step 2: Generate presigned URLs for each part
presigner := s3.NewPresignClient(s3Client)
completedParts := make([]types.CompletedPart, 3)
for partNum := 1; partNum <= numParts; partNum++ {
presignedPart, err := presigner.PresignUploadPart(ctx, &s3.UploadPartInput{
Bucket: &bucket,
Key: &key,
UploadId: uploadID,
PartNumber: aws.Int32(int32(partNum)),
}, s3.WithPresignExpires(1*time.Hour))
if err != nil {
log.Fatalf("failed to generate presigned URL for part %d: %v", partNum, err)
}
fmt.Printf("Presigned URL for part %d: %s\n", partNum, presignedPart.URL)
// generate 5 MB payload
objBody := make([]byte, 5*1024*1024)
for i := range objBody {
objBody[i] = byte(rand.Intn(256))
}
// perform HTTP put to upload the part
_, etag, err := putPart(presignedPart.URL, objBody)
completedParts[partNum-1] = types.CompletedPart{
ETag: aws.String(etag),
PartNumber: aws.Int32(int32(partNum)),
}
}
// After the client uploads each part, you'll collect the ETags and then:
completeMpUploadRes, err := s3Client.CompleteMultipartUpload(ctx, &s3.CompleteMultipartUploadInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
UploadId: uploadID,
MultipartUpload: &types.CompletedMultipartUpload{Parts: completedParts},
})
fmt.Println(completeMpUploadRes)
}
func putPart(url string, data []byte) (int, string, error) {
req, err := http.NewRequest("PUT", url, bytes.NewReader(data))
if err != nil {
return 0, "", fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/octet-stream")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return 0, "", fmt.Errorf("PUT request failed: %w", err)
}
defer resp.Body.Close()
etag := resp.Header.Get("ETag")
etag = strings.ReplaceAll(etag, "\"", "")
return resp.StatusCode, etag, nil
}