105 lines
3.0 KiB
Go
105 lines
3.0 KiB
Go
package s3
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"git.yuntuo.hk/k2safe/go-omni/internal/storagefixture"
|
|
"git.yuntuo.hk/k2safe/go-omni/storage/storagetest"
|
|
"github.com/minio/minio-go/v7"
|
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestS3ProtocolAndR2Config(t *testing.T) {
|
|
server := httptest.NewTLSServer(storagefixture.Handler())
|
|
defer server.Close()
|
|
creds := credentials.NewStaticV4("fixtureAccess", "fixtureSecret", "")
|
|
s, err := Open(Config{Endpoint: strings.TrimPrefix(server.URL, "https://"), Region: "us-east-1", Bucket: "testbucket", Secure: true, MaxBytes: 64, Credentials: creds, Transport: server.Client().Transport})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
storagetest.Run(t, s)
|
|
cfg, err := R2Config(strings.Repeat("a", 32), "bucket", creds)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
r2, err := Open(cfg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
u, err := r2.PresignGet(context.Background(), "path/file", time.Minute)
|
|
if err != nil || u.Host != strings.Repeat("a", 32)+".r2.cloudflarestorage.com" || u.Query().Get("X-Amz-Signature") == "" || !strings.Contains(u.Query().Get("X-Amz-Credential"), "/auto/s3/") {
|
|
t.Fatal("R2 presign settings", err)
|
|
}
|
|
}
|
|
func TestS3Integration(t *testing.T) {
|
|
address := os.Getenv("GO_OMNI_S3_TEST_ADDR")
|
|
if address == "" {
|
|
t.Skip("requires isolated MinIO")
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
|
|
defer cancel()
|
|
ready := false
|
|
for n := 0; n < 100; n++ {
|
|
req, _ := http.NewRequestWithContext(ctx, "GET", "http://"+address+"/minio/health/ready", nil)
|
|
r, err := http.DefaultClient.Do(req)
|
|
if err == nil {
|
|
r.Body.Close()
|
|
if r.StatusCode == 200 {
|
|
ready = true
|
|
break
|
|
}
|
|
}
|
|
if ctx.Err() != nil {
|
|
break
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
if !ready {
|
|
t.Fatal("isolated S3 server did not start")
|
|
}
|
|
client, err := minio.New(address, &minio.Options{Creds: credentials.NewStaticV4("goOmniTest", "goOmniTestSecret", ""), Region: "us-east-1"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
bucket := fmt.Sprintf("test-%d", time.Now().UnixNano())
|
|
if err = client.MakeBucket(ctx, bucket, minio.MakeBucketOptions{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer client.RemoveBucket(context.Background(), bucket)
|
|
s, _ := New(client, bucket, 64)
|
|
storagetest.Run(t, s)
|
|
s.Put(ctx, "signed", strings.NewReader("hello"), 5, "text/plain")
|
|
defer s.Delete(context.Background(), "signed")
|
|
u, err := s.PresignGet(ctx, "signed", time.Minute)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
response, err := http.Get(u.String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw, _ := io.ReadAll(response.Body)
|
|
response.Body.Close()
|
|
if response.StatusCode != 200 || string(raw) != "hello" {
|
|
t.Fatal(response.StatusCode, string(raw))
|
|
}
|
|
q := u.Query()
|
|
q.Set("X-Amz-Signature", strings.Repeat("0", 64))
|
|
u.RawQuery = q.Encode()
|
|
response, err = http.Get(u.String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
response.Body.Close()
|
|
if response.StatusCode != 403 {
|
|
t.Fatal("tampered signature", response.StatusCode)
|
|
}
|
|
}
|