Files
gpt-load/internal/platform/httpheader/request_representation_test.go
tbphp 7ed01e668b feat(images): 支持 Antigravity 与 Gemini 共享生图转换 (#605)
* feat(antigravity): 支持 Images 单向生图转换

* feat(images): 复用转换并支持 Gemini 渠道生图

* fix(images): 修正生图转换失败分类并恢复候选回退
2026-09-09 13:20:10 +08:00

131 lines
3.7 KiB
Go

package httpheader
import (
"net/http"
"reflect"
"strings"
"testing"
)
func TestNormalizeUpstreamRequestRepresentation(t *testing.T) {
source := http.Header{
"Accept-Encoding": {"gzip"},
"accept-encoding": {"br"},
"Content-Encoding": {"zstd"},
"content-encoding": {"deflate"},
"Content-Length": {"999"},
"content-length": {"998"},
"ETag": {`"stale"`},
"Digest": {"sha-256=stale"},
"Content-MD5": {"stale-md5"},
"Content-Range": {"bytes 0-1/2"},
"Content-Digest": {"sha-256=:c3RhbGU=:"},
"Repr-Digest": {"sha-256=:c3RhbGU=:"},
"Signature": {"stale-signature"},
"Signature-Input": {"stale-signature-input"},
"Authorization": {"Bearer secret"},
"Content-Type": {"application/json"},
"X-Business": {"preserved"},
}
original := source.Clone()
request := &http.Request{Header: source, ContentLength: 999}
NormalizeUpstreamRequestRepresentation(request, 37)
if request.ContentLength != 37 {
t.Fatalf("ContentLength = %d, want 37", request.ContentLength)
}
if values := headerFieldValues(request.Header, "Accept-Encoding"); !reflect.DeepEqual(values, []string{"identity"}) {
t.Fatalf("Accept-Encoding values = %#v, want [identity]", values)
}
for _, name := range []string{
"Content-Encoding",
"Content-Length",
"ETag",
"Digest",
"Content-MD5",
"Content-Range",
"Content-Digest",
"Repr-Digest",
"Signature",
"Signature-Input",
} {
if values := headerFieldValues(request.Header, name); values != nil {
t.Errorf("%s values = %#v, want absent", name, values)
}
}
for name, want := range map[string]string{
"Authorization": "Bearer secret",
"Content-Type": "application/json",
"X-Business": "preserved",
} {
if got := request.Header.Get(name); got != want {
t.Errorf("%s = %q, want %q", name, got, want)
}
}
if !reflect.DeepEqual(source, original) {
t.Fatalf("source header map was mutated: got %#v, want %#v", source, original)
}
}
func TestNormalizeUpstreamRequestRepresentationInitializesNilHeader(t *testing.T) {
request := &http.Request{}
NormalizeUpstreamRequestRepresentation(request, 0)
if values := request.Header.Values("Accept-Encoding"); !reflect.DeepEqual(values, []string{"identity"}) {
t.Fatalf("Accept-Encoding values = %#v, want [identity]", values)
}
if request.ContentLength != 0 {
t.Fatalf("ContentLength = %d, want 0", request.ContentLength)
}
}
func TestStripRepresentationMetadataRemovesCaseCollidingFields(t *testing.T) {
headers := http.Header{
"Content-Encoding": {"gzip"},
"content-length": {"123"},
"eTAG": {`"stale"`},
"dIGEST": {"sha-256=stale"},
"content-md5": {"stale-md5"},
"content-range": {"bytes 0-1/2"},
"content-digest": {"sha-256=:c3RhbGU=12:"},
"repr-digest": {"sha-256=:c3RhbGU=12:"},
"signature": {"stale-signature"},
"signature-input": {"sig1=(\"etag\")"},
"Content-Type": {"application/json"},
}
StripRepresentationMetadata(headers)
for _, name := range []string{
"Content-Encoding",
"Content-Length",
"ETag",
"Digest",
"Content-MD5",
"Content-Range",
"Content-Digest",
"Repr-Digest",
"Signature",
"Signature-Input",
} {
if values := headerFieldValues(headers, name); values != nil {
t.Errorf("%s values = %#v, want absent", name, values)
}
}
if got := headers.Get("Content-Type"); got != "application/json" {
t.Fatalf("Content-Type = %q, want preserved value", got)
}
}
func headerFieldValues(headers http.Header, target string) []string {
var values []string
for name, fieldValues := range headers {
if strings.EqualFold(name, target) {
values = append(values, fieldValues...)
}
}
return values
}