88 lines
4.0 KiB
Go
88 lines
4.0 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
agentv1 "git.ipao.vip/rogee/go-sip/gen/agent/v1"
|
|
)
|
|
|
|
func TestUploadClientUsesGrantAndVerifiesChecksum(t *testing.T) {
|
|
body := []byte("mock recording bytes")
|
|
digest := sha256.Sum256(body)
|
|
var received []byte
|
|
var receivedHeader string
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
receivedHeader = r.Header.Get("x-upload-token")
|
|
received, _ = io.ReadAll(r.Body)
|
|
w.Header().Set("ETag", "etag-1")
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
defer server.Close()
|
|
assetPath := filepath.Join(t.TempDir(), "recording.bin")
|
|
if err := os.WriteFile(assetPath, body, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
grant := &agentv1.UploadGrant{UploadId: "upload-1", TargetUrl: server.URL, ObjectKey: "recording-1", ExpiresAtUnixMs: time.Unix(101, 0).UnixMilli(), Headers: []*agentv1.Header{{Name: "x-upload-token", Value: "mock-token"}}, RequiredChecksumSha256: hex.EncodeToString(digest[:]), MaxBytes: int64(len(body))}
|
|
result, err := (UploadClient{AllowInsecureHTTP: true, Now: func() time.Time { return time.Unix(100, 0) }, AllowedHosts: map[string]struct{}{strings.TrimPrefix(server.URL, "http://"): {}}}).UploadFile(context.Background(), grant, assetPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result.StatusCode != http.StatusOK || result.SHA256 != grant.RequiredChecksumSha256 || result.ETag != "etag-1" || string(received) != string(body) || receivedHeader != "mock-token" {
|
|
t.Fatalf("unexpected upload result: %+v body=%q header=%q", result, received, receivedHeader)
|
|
}
|
|
if retained, statErr := os.Stat(assetPath); statErr != nil || retained.Size() != int64(len(body)) {
|
|
t.Fatalf("source asset was not retained after upload: stat=%v info=%v", statErr, retained)
|
|
}
|
|
}
|
|
|
|
func TestUploadClientFailsClosedForGrantMismatchAndHTTP(t *testing.T) {
|
|
assetPath := filepath.Join(t.TempDir(), "recording.bin")
|
|
if err := os.WriteFile(assetPath, []byte("bytes"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
grant := &agentv1.UploadGrant{UploadId: "upload-2", TargetUrl: "http://127.0.0.1:1/upload", ObjectKey: "recording-2", ExpiresAtUnixMs: time.Now().Add(time.Hour).UnixMilli(), RequiredChecksumSha256: strings.Repeat("a", 64), MaxBytes: 1024}
|
|
if _, err := (UploadClient{AllowInsecureHTTP: true}).UploadFile(context.Background(), grant, assetPath); err == nil {
|
|
t.Fatal("expected checksum mismatch")
|
|
}
|
|
grant.RequiredChecksumSha256 = ""
|
|
if _, err := (UploadClient{}).UploadFile(context.Background(), grant, assetPath); err == nil {
|
|
t.Fatal("expected HTTP upload URL rejection")
|
|
}
|
|
}
|
|
|
|
func TestUploadClientEnforcesSizeAndHost(t *testing.T) {
|
|
assetPath := filepath.Join(t.TempDir(), "recording.bin")
|
|
if err := os.WriteFile(assetPath, []byte("bytes"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
grant := &agentv1.UploadGrant{UploadId: "upload-3", TargetUrl: "https://oss.example.invalid/upload", ObjectKey: "recording-3", ExpiresAtUnixMs: time.Now().Add(time.Hour).UnixMilli(), MaxBytes: 1}
|
|
if _, err := (UploadClient{}).UploadFile(context.Background(), grant, assetPath); err == nil {
|
|
t.Fatal("expected size rejection")
|
|
}
|
|
grant.MaxBytes = 1024
|
|
if _, err := (UploadClient{AllowedHosts: map[string]struct{}{"other.example.invalid": {}}}).UploadFile(context.Background(), grant, assetPath); err == nil {
|
|
t.Fatal("expected host rejection")
|
|
}
|
|
}
|
|
|
|
func TestUploadClientRejectsExpiredGrant(t *testing.T) {
|
|
assetPath := filepath.Join(t.TempDir(), "recording.bin")
|
|
if err := os.WriteFile(assetPath, []byte("bytes"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
grant := &agentv1.UploadGrant{UploadId: "upload-expired", TargetUrl: "https://oss.example.invalid/upload", ObjectKey: "recording-expired", ExpiresAtUnixMs: time.Unix(100, 0).UnixMilli(), MaxBytes: 1024}
|
|
if _, err := (UploadClient{Now: func() time.Time { return time.Unix(100, 0) }}).UploadFile(context.Background(), grant, assetPath); err == nil {
|
|
t.Fatal("expected expired grant rejection")
|
|
}
|
|
}
|