Files
spray/pkg/utils_test.go
T
2026-05-08 10:12:56 -07:00

123 lines
3.6 KiB
Go

package pkg
import (
"strings"
"testing"
)
func TestParseRawResponse(t *testing.T) {
t.Run("valid complete response", func(t *testing.T) {
raw := "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 5\r\n\r\nhello"
resp, err := ParseRawResponse([]byte(raw))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != 200 {
t.Fatalf("expected status 200, got %d", resp.StatusCode)
}
if ct := resp.Header.Get("Content-Type"); ct != "text/html" {
t.Fatalf("expected Content-Type text/html, got %s", ct)
}
})
t.Run("nil input", func(t *testing.T) {
_, err := ParseRawResponse(nil)
if err == nil {
t.Fatal("expected error for nil input")
}
})
t.Run("empty input", func(t *testing.T) {
_, err := ParseRawResponse([]byte{})
if err == nil {
t.Fatal("expected error for empty input")
}
})
t.Run("status line only no headers", func(t *testing.T) {
raw := "HTTP/1.1 200 OK\r\n\r\n"
resp, err := ParseRawResponse([]byte(raw))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != 200 {
t.Fatalf("expected status 200, got %d", resp.StatusCode)
}
})
t.Run("truncated status line", func(t *testing.T) {
raw := "HTTP/1."
_, err := ParseRawResponse([]byte(raw))
if err == nil {
t.Fatal("expected error for truncated status line")
}
})
t.Run("redirect response no body", func(t *testing.T) {
raw := "HTTP/1.1 302 Found\r\nLocation: https://example.com/new\r\n\r\n"
resp, err := ParseRawResponse([]byte(raw))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != 302 {
t.Fatalf("expected status 302, got %d", resp.StatusCode)
}
if loc := resp.Header.Get("Location"); loc != "https://example.com/new" {
t.Fatalf("expected Location https://example.com/new, got %s", loc)
}
})
t.Run("chunked transfer encoding header", func(t *testing.T) {
raw := "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
resp, err := ParseRawResponse([]byte(raw))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if te := resp.Header.Get("Transfer-Encoding"); te == "" {
// Transfer-Encoding may be consumed by http.ReadResponse, just verify no panic
}
_ = resp
})
t.Run("large header value", func(t *testing.T) {
largeValue := strings.Repeat("A", 8192)
raw := "HTTP/1.1 200 OK\r\nX-Large: " + largeValue + "\r\n\r\n"
resp, err := ParseRawResponse([]byte(raw))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got := resp.Header.Get("X-Large"); got != largeValue {
t.Fatalf("large header value mismatch, got length %d", len(got))
}
})
t.Run("invalid status code", func(t *testing.T) {
raw := "HTTP/1.1 xyz OK\r\n\r\n"
_, err := ParseRawResponse([]byte(raw))
if err == nil {
t.Fatal("expected error for invalid status code")
}
})
t.Run("incomplete header no terminator", func(t *testing.T) {
raw := "HTTP/1.1 200 OK\r\nContent-Type: text/html"
_, err := ParseRawResponse([]byte(raw))
// Should return error or at least not panic
// http.ReadResponse may or may not error on missing \r\n\r\n,
// the key requirement is no panic
_ = err
})
t.Run("binary body", func(t *testing.T) {
body := []byte{0x00, 0x01, 0x02, 0xff, 0xfe, 0xfd}
raw := append([]byte("HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\n"), body...)
resp, err := ParseRawResponse(raw)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != 200 {
t.Fatalf("expected status 200, got %d", resp.StatusCode)
}
})
}