http/client_test.go

141 lines
3.2 KiB
Go

package http
import (
"fmt"
"io"
"net"
"net/http"
"testing"
"time"
"golang.org/x/net/http2"
)
func TestHttp(t *testing.T) {
c := NewClient(5 * time.Second)
// 使用 httpbin 或者可靠的地址
r := c.Get("https://httpbin.org/get")
if r.Error != nil {
t.Skip("network unreachable, skipping remote test:", r.Error)
return
}
if r.Response.StatusCode != 200 {
t.Errorf("expected 200, got %d", r.Response.StatusCode)
}
type HttpBinGet struct {
Url string
}
res, err := ToT[HttpBinGet](r)
if err != nil {
t.Errorf("ToT failed: %v", err)
}
if res.Url != "https://httpbin.org/get" {
t.Errorf("expected url match, got %s", res.Url)
}
}
func TestLocalServer(t *testing.T) {
handler := http.NewServeMux()
handler.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Test-Echo", r.Header.Get("X-Test"))
_, _ = w.Write([]byte("world"))
})
server := &http.Server{Addr: ":18080", Handler: handler}
go func() { _ = server.ListenAndServe() }()
defer server.Close()
// 等待启动
time.Sleep(100 * time.Millisecond)
c := NewClient(time.Second)
r := c.Get("http://127.0.0.1:18080/hello", "X-Test", "hi")
if r.Error != nil {
t.Fatalf("request failed: %v", r.Error)
}
if r.String() != "world" {
t.Errorf("expected world, got %s", r.String())
}
if r.Response.Header.Get("X-Test-Echo") != "hi" {
t.Errorf("header not echoed")
}
}
func TestH2C(t *testing.T) {
ln, err := net.Listen("tcp", "127.0.0.1:18081")
if err != nil {
t.Fatalf("failed to listen: %v", err)
}
defer ln.Close()
s2 := &http2.Server{}
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello H2C")
})
go func() {
for {
conn, err := ln.Accept()
if err != nil {
return
}
go s2.ServeConn(conn, &http2.ServeConnOpts{
Handler: handler,
})
}
}()
c := NewClientH2C(time.Second)
r := c.Get("http://127.0.0.1:18081/")
if r.Error != nil {
t.Fatalf("h2c request failed: %v", r.Error)
}
if r.String() != "Hello H2C" {
t.Errorf("expected Hello H2C, got %s", r.String())
}
}
func BenchmarkGet(b *testing.B) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("ok"))
})
server := &http.Server{Addr: ":18082", Handler: handler}
go func() { _ = server.ListenAndServe() }()
defer server.Close()
time.Sleep(100 * time.Millisecond)
c := NewClient(0)
b.ResetTimer()
for i := 0; i < b.N; i++ {
r := c.Get("http://127.0.0.1:18082/")
if r.Error != nil {
b.Fatal(r.Error)
}
}
}
func TestManualDo(t *testing.T) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("stream"))
})
server := &http.Server{Addr: ":18083", Handler: handler}
go func() { _ = server.ListenAndServe() }()
defer server.Close()
time.Sleep(100 * time.Millisecond)
c := NewClient(time.Second)
r := c.ManualDo("GET", "http://127.0.0.1:18083/", nil)
if r.Error != nil {
t.Fatal(r.Error)
}
if r.data != nil {
t.Error("expected data to be nil in ManualDo")
}
defer r.Response.Body.Close()
buf, _ := io.ReadAll(r.Response.Body)
if string(buf) != "stream" {
t.Errorf("expected stream, got %s", string(buf))
}
}