mirror of https://github.com/gofiber/fiber.git
1737 lines
37 KiB
Go
1737 lines
37 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"encoding/hex"
|
|
"errors"
|
|
"io"
|
|
"net"
|
|
"os"
|
|
"reflect"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
"github.com/gofiber/fiber/v3/addon/retry"
|
|
"github.com/gofiber/fiber/v3/internal/tlstest"
|
|
"github.com/gofiber/utils/v2"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/valyala/bytebufferpool"
|
|
"github.com/valyala/fasthttp"
|
|
)
|
|
|
|
func startTestServerWithPort(t *testing.T, beforeStarting func(app *fiber.App)) (*fiber.App, string) {
|
|
t.Helper()
|
|
|
|
app := fiber.New()
|
|
|
|
if beforeStarting != nil {
|
|
beforeStarting(app)
|
|
}
|
|
|
|
addrChan := make(chan string)
|
|
errChan := make(chan error, 1)
|
|
go func() {
|
|
err := app.Listen(":0", fiber.ListenConfig{
|
|
DisableStartupMessage: true,
|
|
ListenerAddrFunc: func(addr net.Addr) {
|
|
addrChan <- addr.String()
|
|
},
|
|
})
|
|
if err != nil {
|
|
errChan <- err
|
|
}
|
|
}()
|
|
|
|
select {
|
|
case addr := <-addrChan:
|
|
return app, addr
|
|
case err := <-errChan:
|
|
t.Fatalf("Failed to start test server: %v", err)
|
|
}
|
|
|
|
return nil, ""
|
|
}
|
|
|
|
func Test_New_With_Client(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("with valid client", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
c := &fasthttp.Client{
|
|
MaxConnsPerHost: 5,
|
|
}
|
|
client := NewWithClient(c)
|
|
|
|
require.NotNil(t, client)
|
|
})
|
|
|
|
t.Run("with nil client", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
require.PanicsWithValue(t, "fasthttp.Client must not be nil", func() {
|
|
NewWithClient(nil)
|
|
})
|
|
})
|
|
}
|
|
|
|
func Test_Client_Add_Hook(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("add request hooks", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
buf := bytebufferpool.Get()
|
|
defer bytebufferpool.Put(buf)
|
|
|
|
client := New().AddRequestHook(func(_ *Client, _ *Request) error {
|
|
buf.WriteString("hook1")
|
|
return nil
|
|
})
|
|
|
|
require.Len(t, client.RequestHook(), 1)
|
|
|
|
client.AddRequestHook(func(_ *Client, _ *Request) error {
|
|
buf.WriteString("hook2")
|
|
return nil
|
|
}, func(_ *Client, _ *Request) error {
|
|
buf.WriteString("hook3")
|
|
return nil
|
|
})
|
|
|
|
require.Len(t, client.RequestHook(), 3)
|
|
})
|
|
|
|
t.Run("add response hooks", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().AddResponseHook(func(_ *Client, _ *Response, _ *Request) error {
|
|
return nil
|
|
})
|
|
|
|
require.Len(t, client.ResponseHook(), 1)
|
|
|
|
client.AddResponseHook(func(_ *Client, _ *Response, _ *Request) error {
|
|
return nil
|
|
}, func(_ *Client, _ *Response, _ *Request) error {
|
|
return nil
|
|
})
|
|
|
|
require.Len(t, client.ResponseHook(), 3)
|
|
})
|
|
}
|
|
|
|
func Test_Client_Add_Hook_CheckOrder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
buf := bytebufferpool.Get()
|
|
defer bytebufferpool.Put(buf)
|
|
|
|
client := New().
|
|
AddRequestHook(func(_ *Client, _ *Request) error {
|
|
buf.WriteString("hook1")
|
|
return nil
|
|
}).
|
|
AddRequestHook(func(_ *Client, _ *Request) error {
|
|
buf.WriteString("hook2")
|
|
return nil
|
|
}).
|
|
AddRequestHook(func(_ *Client, _ *Request) error {
|
|
buf.WriteString("hook3")
|
|
return nil
|
|
})
|
|
|
|
for _, hook := range client.RequestHook() {
|
|
require.NoError(t, hook(client, &Request{}))
|
|
}
|
|
|
|
require.Equal(t, "hook1hook2hook3", buf.String())
|
|
}
|
|
|
|
func Test_Client_Marshal(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("set json marshal", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().
|
|
SetJSONMarshal(func(_ any) ([]byte, error) {
|
|
return []byte("hello"), nil
|
|
})
|
|
val, err := client.JSONMarshal()(nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, []byte("hello"), val)
|
|
})
|
|
|
|
t.Run("set json marshal error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
emptyErr := errors.New("empty json")
|
|
client := New().
|
|
SetJSONMarshal(func(_ any) ([]byte, error) {
|
|
return nil, emptyErr
|
|
})
|
|
|
|
val, err := client.JSONMarshal()(nil)
|
|
require.Nil(t, val)
|
|
require.ErrorIs(t, err, emptyErr)
|
|
})
|
|
|
|
t.Run("set json unmarshal", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().
|
|
SetJSONUnmarshal(func(_ []byte, _ any) error {
|
|
return errors.New("empty json")
|
|
})
|
|
|
|
err := client.JSONUnmarshal()(nil, nil)
|
|
require.Equal(t, errors.New("empty json"), err)
|
|
})
|
|
|
|
t.Run("set json unmarshal error", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().
|
|
SetJSONUnmarshal(func(_ []byte, _ any) error {
|
|
return errors.New("empty json")
|
|
})
|
|
|
|
err := client.JSONUnmarshal()(nil, nil)
|
|
require.Equal(t, errors.New("empty json"), err)
|
|
})
|
|
|
|
t.Run("set xml marshal", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().
|
|
SetXMLMarshal(func(_ any) ([]byte, error) {
|
|
return []byte("hello"), nil
|
|
})
|
|
val, err := client.XMLMarshal()(nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, []byte("hello"), val)
|
|
})
|
|
|
|
t.Run("set xml marshal error", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().
|
|
SetXMLMarshal(func(_ any) ([]byte, error) {
|
|
return nil, errors.New("empty xml")
|
|
})
|
|
|
|
val, err := client.XMLMarshal()(nil)
|
|
require.Nil(t, val)
|
|
require.Equal(t, errors.New("empty xml"), err)
|
|
})
|
|
|
|
t.Run("set cbor marshal", func(t *testing.T) {
|
|
t.Parallel()
|
|
bs, err := hex.DecodeString("f6")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
client := New().
|
|
SetCBORMarshal(func(_ any) ([]byte, error) {
|
|
return bs, nil
|
|
})
|
|
val, err := client.CBORMarshal()(nil)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, bs, val)
|
|
})
|
|
|
|
t.Run("set cbor marshal error", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().SetCBORMarshal(func(_ any) ([]byte, error) {
|
|
return nil, errors.New("invalid struct")
|
|
})
|
|
|
|
val, err := client.CBORMarshal()(nil)
|
|
require.Nil(t, val)
|
|
require.Equal(t, errors.New("invalid struct"), err)
|
|
})
|
|
|
|
t.Run("set xml unmarshal", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().
|
|
SetXMLUnmarshal(func(_ []byte, _ any) error {
|
|
return errors.New("empty xml")
|
|
})
|
|
|
|
err := client.XMLUnmarshal()(nil, nil)
|
|
require.Equal(t, errors.New("empty xml"), err)
|
|
})
|
|
|
|
t.Run("set xml unmarshal error", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New().
|
|
SetXMLUnmarshal(func(_ []byte, _ any) error {
|
|
return errors.New("empty xml")
|
|
})
|
|
|
|
err := client.XMLUnmarshal()(nil, nil)
|
|
require.Equal(t, errors.New("empty xml"), err)
|
|
})
|
|
}
|
|
|
|
func Test_Client_SetBaseURL(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
client := New().SetBaseURL("http://example.com")
|
|
|
|
require.Equal(t, "http://example.com", client.BaseURL())
|
|
}
|
|
|
|
func Test_Client_Invalid_URL(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, dial, start := createHelperServer(t)
|
|
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString(c.Hostname())
|
|
})
|
|
|
|
go start()
|
|
|
|
_, err := New().SetDial(dial).
|
|
R().
|
|
Get("http//example")
|
|
|
|
require.ErrorIs(t, err, ErrURLFormat)
|
|
}
|
|
|
|
func Test_Client_Unsupported_Protocol(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := New().
|
|
R().
|
|
Get("ftp://example.com")
|
|
|
|
require.ErrorIs(t, err, ErrURLFormat)
|
|
}
|
|
|
|
func Test_Client_ConcurrencyRequests(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, dial, start := createHelperServer(t)
|
|
app.All("/", func(c fiber.Ctx) error {
|
|
return c.SendString(c.Hostname() + " " + c.Method())
|
|
})
|
|
go start()
|
|
|
|
client := New().SetDial(dial)
|
|
|
|
wg := sync.WaitGroup{}
|
|
for i := 0; i < 5; i++ {
|
|
for _, method := range []string{"GET", "POST", "PUT", "DELETE", "PATCH"} {
|
|
wg.Add(1)
|
|
go func(m string) {
|
|
defer wg.Done()
|
|
resp, err := client.Custom("http://example.com", m)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "example.com "+m, utils.UnsafeString(resp.RawResponse.Body()))
|
|
}(method)
|
|
}
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|
|
|
|
func Test_Get(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString(c.Hostname())
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("global get function", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
resp, err := Get("http://" + addr)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "0.0.0.0", utils.UnsafeString(resp.RawResponse.Body()))
|
|
})
|
|
|
|
t.Run("client get", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
resp, err := New().Get("http://" + addr)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "0.0.0.0", utils.UnsafeString(resp.RawResponse.Body()))
|
|
})
|
|
}
|
|
|
|
func Test_Head(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Head("/", func(c fiber.Ctx) error {
|
|
return c.SendString(c.Hostname())
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("global head function", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
resp, err := Head("http://" + addr)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "7", resp.Header(fiber.HeaderContentLength))
|
|
require.Equal(t, "", utils.UnsafeString(resp.RawResponse.Body()))
|
|
})
|
|
|
|
t.Run("client head", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
resp, err := New().Head("http://" + addr)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "7", resp.Header(fiber.HeaderContentLength))
|
|
require.Equal(t, "", utils.UnsafeString(resp.RawResponse.Body()))
|
|
})
|
|
}
|
|
|
|
func Test_Post(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Post("/", func(c fiber.Ctx) error {
|
|
return c.Status(fiber.StatusCreated).
|
|
SendString(c.FormValue("foo"))
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("global post function", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := Post("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusCreated, resp.StatusCode())
|
|
require.Equal(t, "bar", resp.String())
|
|
}
|
|
})
|
|
|
|
t.Run("client post", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := New().Post("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusCreated, resp.StatusCode())
|
|
require.Equal(t, "bar", resp.String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_Put(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Put("/", func(c fiber.Ctx) error {
|
|
return c.SendString(c.FormValue("foo"))
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("global put function", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := Put("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "bar", resp.String())
|
|
}
|
|
})
|
|
|
|
t.Run("client put", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := New().Put("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "bar", resp.String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_Delete(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Delete("/", func(c fiber.Ctx) error {
|
|
return c.Status(fiber.StatusNoContent).
|
|
SendString("deleted")
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("global delete function", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := Delete("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusNoContent, resp.StatusCode())
|
|
require.Equal(t, "", resp.String())
|
|
}
|
|
})
|
|
|
|
t.Run("client delete", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := New().Delete("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusNoContent, resp.StatusCode())
|
|
require.Equal(t, "", resp.String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_Options(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Options("/", func(c fiber.Ctx) error {
|
|
c.Set(fiber.HeaderAllow, "GET, POST, PUT, DELETE, PATCH")
|
|
return c.Status(fiber.StatusNoContent).SendString("")
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("global options function", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := Options("http://" + addr)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "GET, POST, PUT, DELETE, PATCH", resp.Header(fiber.HeaderAllow))
|
|
require.Equal(t, fiber.StatusNoContent, resp.StatusCode())
|
|
require.Equal(t, "", resp.String())
|
|
}
|
|
})
|
|
|
|
t.Run("client options", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := New().Options("http://" + addr)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, "GET, POST, PUT, DELETE, PATCH", resp.Header(fiber.HeaderAllow))
|
|
require.Equal(t, fiber.StatusNoContent, resp.StatusCode())
|
|
require.Equal(t, "", resp.String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_Patch(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Patch("/", func(c fiber.Ctx) error {
|
|
return c.SendString(c.FormValue("foo"))
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("global patch function", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := Patch("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "bar", resp.String())
|
|
}
|
|
})
|
|
|
|
t.Run("client patch", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := New().Patch("http://"+addr, Config{
|
|
FormData: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "bar", resp.String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_Client_UserAgent(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
setupApp := func() (*fiber.App, string) {
|
|
app, addr := startTestServerWithPort(t, func(app *fiber.App) {
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.Send(c.Request().Header.UserAgent())
|
|
})
|
|
})
|
|
|
|
return app, addr
|
|
}
|
|
|
|
t.Run("default", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
resp, err := Get("http://" + addr)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, defaultUserAgent, resp.String())
|
|
}
|
|
})
|
|
|
|
t.Run("custom", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, addr := setupApp()
|
|
defer func() {
|
|
require.NoError(t, app.Shutdown())
|
|
}()
|
|
|
|
for i := 0; i < 5; i++ {
|
|
c := New().
|
|
SetUserAgent("ua")
|
|
|
|
resp, err := c.Get("http://" + addr)
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "ua", resp.String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_Client_Header(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("add header", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.AddHeader("foo", "bar").AddHeader("foo", "fiber")
|
|
|
|
res := req.Header("foo")
|
|
require.Len(t, res, 2)
|
|
require.Equal(t, "bar", res[0])
|
|
require.Equal(t, "fiber", res[1])
|
|
})
|
|
|
|
t.Run("set header", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.AddHeader("foo", "bar").SetHeader("foo", "fiber")
|
|
|
|
res := req.Header("foo")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "fiber", res[0])
|
|
})
|
|
|
|
t.Run("add headers", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.SetHeader("foo", "bar").
|
|
AddHeaders(map[string][]string{
|
|
"foo": {"fiber", "buaa"},
|
|
"bar": {"foo"},
|
|
})
|
|
|
|
res := req.Header("foo")
|
|
require.Len(t, res, 3)
|
|
require.Equal(t, "bar", res[0])
|
|
require.Equal(t, "fiber", res[1])
|
|
require.Equal(t, "buaa", res[2])
|
|
|
|
res = req.Header("bar")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "foo", res[0])
|
|
})
|
|
|
|
t.Run("set headers", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.SetHeader("foo", "bar").
|
|
SetHeaders(map[string]string{
|
|
"foo": "fiber",
|
|
"bar": "foo",
|
|
})
|
|
|
|
res := req.Header("foo")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "fiber", res[0])
|
|
|
|
res = req.Header("bar")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "foo", res[0])
|
|
})
|
|
|
|
t.Run("set header case insensitive", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.SetHeader("foo", "bar").
|
|
AddHeader("FOO", "fiber")
|
|
|
|
res := req.Header("foo")
|
|
require.Len(t, res, 2)
|
|
require.Equal(t, "bar", res[0])
|
|
require.Equal(t, "fiber", res[1])
|
|
})
|
|
}
|
|
|
|
func Test_Client_Header_With_Server(t *testing.T) {
|
|
handler := func(c fiber.Ctx) error {
|
|
c.Request().Header.VisitAll(func(key, value []byte) {
|
|
if k := string(key); k == "K1" || k == "K2" {
|
|
_, _ = c.Write(key) //nolint:errcheck // It is fine to ignore the error here
|
|
_, _ = c.Write(value) //nolint:errcheck // It is fine to ignore the error here
|
|
}
|
|
})
|
|
return nil
|
|
}
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetHeader("k1", "v1").
|
|
AddHeader("k1", "v11").
|
|
AddHeaders(map[string][]string{
|
|
"k1": {"v22", "v33"},
|
|
}).
|
|
SetHeaders(map[string]string{
|
|
"k2": "v2",
|
|
}).
|
|
AddHeader("k2", "v22")
|
|
}
|
|
|
|
testClient(t, handler, wrapAgent, "K1v1K1v11K1v22K1v33K2v2K2v22")
|
|
}
|
|
|
|
func Test_Client_Cookie(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("set cookie", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New().
|
|
SetCookie("foo", "bar")
|
|
require.Equal(t, "bar", req.Cookie("foo"))
|
|
|
|
req.SetCookie("foo", "bar1")
|
|
require.Equal(t, "bar1", req.Cookie("foo"))
|
|
})
|
|
|
|
t.Run("set cookies", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New().
|
|
SetCookies(map[string]string{
|
|
"foo": "bar",
|
|
"bar": "foo",
|
|
})
|
|
require.Equal(t, "bar", req.Cookie("foo"))
|
|
require.Equal(t, "foo", req.Cookie("bar"))
|
|
|
|
req.SetCookies(map[string]string{
|
|
"foo": "bar1",
|
|
})
|
|
require.Equal(t, "bar1", req.Cookie("foo"))
|
|
require.Equal(t, "foo", req.Cookie("bar"))
|
|
})
|
|
|
|
t.Run("set cookies with struct", func(t *testing.T) {
|
|
t.Parallel()
|
|
type args struct {
|
|
CookieString string `cookie:"string"`
|
|
CookieInt int `cookie:"int"`
|
|
}
|
|
|
|
req := New().SetCookiesWithStruct(&args{
|
|
CookieInt: 5,
|
|
CookieString: "foo",
|
|
})
|
|
|
|
require.Equal(t, "5", req.Cookie("int"))
|
|
require.Equal(t, "foo", req.Cookie("string"))
|
|
})
|
|
|
|
t.Run("del cookies", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New().
|
|
SetCookies(map[string]string{
|
|
"foo": "bar",
|
|
"bar": "foo",
|
|
})
|
|
require.Equal(t, "bar", req.Cookie("foo"))
|
|
require.Equal(t, "foo", req.Cookie("bar"))
|
|
|
|
req.DelCookies("foo")
|
|
require.Equal(t, "", req.Cookie("foo"))
|
|
require.Equal(t, "foo", req.Cookie("bar"))
|
|
})
|
|
}
|
|
|
|
func Test_Client_Cookie_With_Server(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
handler := func(c fiber.Ctx) error {
|
|
return c.SendString(
|
|
c.Cookies("k1") + c.Cookies("k2") + c.Cookies("k3") + c.Cookies("k4"))
|
|
}
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetCookie("k1", "v1").
|
|
SetCookies(map[string]string{
|
|
"k2": "v2",
|
|
"k3": "v3",
|
|
"k4": "v4",
|
|
}).DelCookies("k4")
|
|
}
|
|
|
|
testClient(t, handler, wrapAgent, "v1v2v3")
|
|
}
|
|
|
|
func Test_Client_CookieJar(t *testing.T) {
|
|
handler := func(c fiber.Ctx) error {
|
|
return c.SendString(
|
|
c.Cookies("k1") + c.Cookies("k2") + c.Cookies("k3"))
|
|
}
|
|
|
|
jar := AcquireCookieJar()
|
|
defer ReleaseCookieJar(jar)
|
|
|
|
jar.SetKeyValue("example.com", "k1", "v1")
|
|
jar.SetKeyValue("example.com", "k2", "v2")
|
|
jar.SetKeyValue("example", "k3", "v3")
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetCookieJar(jar)
|
|
}
|
|
testClient(t, handler, wrapAgent, "v1v2")
|
|
}
|
|
|
|
func Test_Client_CookieJar_Response(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("without expiration", func(t *testing.T) {
|
|
t.Parallel()
|
|
handler := func(c fiber.Ctx) error {
|
|
c.Cookie(&fiber.Cookie{
|
|
Name: "k4",
|
|
Value: "v4",
|
|
})
|
|
return c.SendString(
|
|
c.Cookies("k1") + c.Cookies("k2") + c.Cookies("k3"))
|
|
}
|
|
|
|
jar := AcquireCookieJar()
|
|
defer ReleaseCookieJar(jar)
|
|
|
|
jar.SetKeyValue("example.com", "k1", "v1")
|
|
jar.SetKeyValue("example.com", "k2", "v2")
|
|
jar.SetKeyValue("example", "k3", "v3")
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetCookieJar(jar)
|
|
}
|
|
testClient(t, handler, wrapAgent, "v1v2")
|
|
|
|
require.Len(t, jar.getCookiesByHost("example.com"), 3)
|
|
})
|
|
|
|
t.Run("with expiration", func(t *testing.T) {
|
|
t.Parallel()
|
|
handler := func(c fiber.Ctx) error {
|
|
c.Cookie(&fiber.Cookie{
|
|
Name: "k4",
|
|
Value: "v4",
|
|
Expires: time.Now().Add(1 * time.Nanosecond),
|
|
})
|
|
return c.SendString(
|
|
c.Cookies("k1") + c.Cookies("k2") + c.Cookies("k3"))
|
|
}
|
|
|
|
jar := AcquireCookieJar()
|
|
defer ReleaseCookieJar(jar)
|
|
|
|
jar.SetKeyValue("example.com", "k1", "v1")
|
|
jar.SetKeyValue("example.com", "k2", "v2")
|
|
jar.SetKeyValue("example", "k3", "v3")
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetCookieJar(jar)
|
|
}
|
|
testClient(t, handler, wrapAgent, "v1v2")
|
|
|
|
require.Len(t, jar.getCookiesByHost("example.com"), 2)
|
|
})
|
|
|
|
t.Run("override cookie value", func(t *testing.T) {
|
|
t.Parallel()
|
|
handler := func(c fiber.Ctx) error {
|
|
c.Cookie(&fiber.Cookie{
|
|
Name: "k1",
|
|
Value: "v2",
|
|
})
|
|
return c.SendString(
|
|
c.Cookies("k1") + c.Cookies("k2"))
|
|
}
|
|
|
|
jar := AcquireCookieJar()
|
|
defer ReleaseCookieJar(jar)
|
|
|
|
jar.SetKeyValue("example.com", "k1", "v1")
|
|
jar.SetKeyValue("example.com", "k2", "v2")
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetCookieJar(jar)
|
|
}
|
|
testClient(t, handler, wrapAgent, "v1v2")
|
|
|
|
for _, cookie := range jar.getCookiesByHost("example.com") {
|
|
if string(cookie.Key()) == "k1" {
|
|
require.Equal(t, "v2", string(cookie.Value()))
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("different domain", func(t *testing.T) {
|
|
t.Parallel()
|
|
handler := func(c fiber.Ctx) error {
|
|
return c.SendString(c.Cookies("k1"))
|
|
}
|
|
|
|
jar := AcquireCookieJar()
|
|
defer ReleaseCookieJar(jar)
|
|
|
|
jar.SetKeyValue("example.com", "k1", "v1")
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetCookieJar(jar)
|
|
}
|
|
testClient(t, handler, wrapAgent, "v1")
|
|
|
|
require.Len(t, jar.getCookiesByHost("example.com"), 1)
|
|
require.Empty(t, jar.getCookiesByHost("example"))
|
|
})
|
|
}
|
|
|
|
func Test_Client_Referer(t *testing.T) {
|
|
handler := func(c fiber.Ctx) error {
|
|
return c.Send(c.Request().Header.Referer())
|
|
}
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetReferer("http://referer.com")
|
|
}
|
|
|
|
testClient(t, handler, wrapAgent, "http://referer.com")
|
|
}
|
|
|
|
func Test_Client_QueryParam(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("add param", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.AddParam("foo", "bar").AddParam("foo", "fiber")
|
|
|
|
res := req.Param("foo")
|
|
require.Len(t, res, 2)
|
|
require.Equal(t, "bar", res[0])
|
|
require.Equal(t, "fiber", res[1])
|
|
})
|
|
|
|
t.Run("set param", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.AddParam("foo", "bar").SetParam("foo", "fiber")
|
|
|
|
res := req.Param("foo")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "fiber", res[0])
|
|
})
|
|
|
|
t.Run("add params", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.SetParam("foo", "bar").
|
|
AddParams(map[string][]string{
|
|
"foo": {"fiber", "buaa"},
|
|
"bar": {"foo"},
|
|
})
|
|
|
|
res := req.Param("foo")
|
|
require.Len(t, res, 3)
|
|
require.Equal(t, "bar", res[0])
|
|
require.Equal(t, "fiber", res[1])
|
|
require.Equal(t, "buaa", res[2])
|
|
|
|
res = req.Param("bar")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "foo", res[0])
|
|
})
|
|
|
|
t.Run("set headers", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.SetParam("foo", "bar").
|
|
SetParams(map[string]string{
|
|
"foo": "fiber",
|
|
"bar": "foo",
|
|
})
|
|
|
|
res := req.Param("foo")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "fiber", res[0])
|
|
|
|
res = req.Param("bar")
|
|
require.Len(t, res, 1)
|
|
require.Equal(t, "foo", res[0])
|
|
})
|
|
|
|
t.Run("set params with struct", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type args struct {
|
|
TString string
|
|
TSlice []string
|
|
TIntSlice []int `param:"int_slice"`
|
|
TInt int
|
|
TFloat float64
|
|
TBool bool
|
|
}
|
|
|
|
p := New()
|
|
p.SetParamsWithStruct(&args{
|
|
TInt: 5,
|
|
TString: "string",
|
|
TFloat: 3.1,
|
|
TBool: true,
|
|
TSlice: []string{"foo", "bar"},
|
|
TIntSlice: []int{1, 2},
|
|
})
|
|
|
|
require.Empty(t, p.Param("unexport"))
|
|
|
|
require.Len(t, p.Param("TInt"), 1)
|
|
require.Equal(t, "5", p.Param("TInt")[0])
|
|
|
|
require.Len(t, p.Param("TString"), 1)
|
|
require.Equal(t, "string", p.Param("TString")[0])
|
|
|
|
require.Len(t, p.Param("TFloat"), 1)
|
|
require.Equal(t, "3.1", p.Param("TFloat")[0])
|
|
|
|
require.Len(t, p.Param("TBool"), 1)
|
|
|
|
tslice := p.Param("TSlice")
|
|
require.Len(t, tslice, 2)
|
|
require.Equal(t, "foo", tslice[0])
|
|
require.Equal(t, "bar", tslice[1])
|
|
|
|
tint := p.Param("TSlice")
|
|
require.Len(t, tint, 2)
|
|
require.Equal(t, "foo", tint[0])
|
|
require.Equal(t, "bar", tint[1])
|
|
})
|
|
|
|
t.Run("del params", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New()
|
|
req.SetParam("foo", "bar").
|
|
SetParams(map[string]string{
|
|
"foo": "fiber",
|
|
"bar": "foo",
|
|
}).DelParams("foo", "bar")
|
|
|
|
res := req.Param("foo")
|
|
require.Empty(t, res)
|
|
|
|
res = req.Param("bar")
|
|
require.Empty(t, res)
|
|
})
|
|
}
|
|
|
|
func Test_Client_QueryParam_With_Server(t *testing.T) {
|
|
handler := func(c fiber.Ctx) error {
|
|
_, _ = c.WriteString(c.Query("k1")) //nolint:errcheck // It is fine to ignore the error here
|
|
_, _ = c.WriteString(c.Query("k2")) //nolint:errcheck // It is fine to ignore the error here
|
|
|
|
return nil
|
|
}
|
|
|
|
wrapAgent := func(c *Client) {
|
|
c.SetParam("k1", "v1").
|
|
AddParam("k2", "v2")
|
|
}
|
|
|
|
testClient(t, handler, wrapAgent, "v1v2")
|
|
}
|
|
|
|
func Test_Client_PathParam(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("set path param", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New().
|
|
SetPathParam("foo", "bar")
|
|
require.Equal(t, "bar", req.PathParam("foo"))
|
|
|
|
req.SetPathParam("foo", "bar1")
|
|
require.Equal(t, "bar1", req.PathParam("foo"))
|
|
})
|
|
|
|
t.Run("set path params", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New().
|
|
SetPathParams(map[string]string{
|
|
"foo": "bar",
|
|
"bar": "foo",
|
|
})
|
|
require.Equal(t, "bar", req.PathParam("foo"))
|
|
require.Equal(t, "foo", req.PathParam("bar"))
|
|
|
|
req.SetPathParams(map[string]string{
|
|
"foo": "bar1",
|
|
})
|
|
require.Equal(t, "bar1", req.PathParam("foo"))
|
|
require.Equal(t, "foo", req.PathParam("bar"))
|
|
})
|
|
|
|
t.Run("set path params with struct", func(t *testing.T) {
|
|
t.Parallel()
|
|
type args struct {
|
|
CookieString string `path:"string"`
|
|
CookieInt int `path:"int"`
|
|
}
|
|
|
|
req := New().SetPathParamsWithStruct(&args{
|
|
CookieInt: 5,
|
|
CookieString: "foo",
|
|
})
|
|
|
|
require.Equal(t, "5", req.PathParam("int"))
|
|
require.Equal(t, "foo", req.PathParam("string"))
|
|
})
|
|
|
|
t.Run("del path params", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := New().
|
|
SetPathParams(map[string]string{
|
|
"foo": "bar",
|
|
"bar": "foo",
|
|
})
|
|
require.Equal(t, "bar", req.PathParam("foo"))
|
|
require.Equal(t, "foo", req.PathParam("bar"))
|
|
|
|
req.DelPathParams("foo")
|
|
require.Equal(t, "", req.PathParam("foo"))
|
|
require.Equal(t, "foo", req.PathParam("bar"))
|
|
})
|
|
}
|
|
|
|
func Test_Client_PathParam_With_Server(t *testing.T) {
|
|
app, dial, start := createHelperServer(t)
|
|
|
|
app.Get("/:test", func(c fiber.Ctx) error {
|
|
return c.SendString(c.Params("test"))
|
|
})
|
|
|
|
go start()
|
|
|
|
resp, err := New().SetDial(dial).
|
|
SetPathParam("path", "test").
|
|
Get("http://example.com/:path")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "test", resp.String())
|
|
}
|
|
|
|
func Test_Client_TLS(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
serverTLSConf, clientTLSConf, err := tlstest.GetTLSConfigs()
|
|
require.NoError(t, err)
|
|
|
|
ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
|
|
ln = tls.NewListener(ln, serverTLSConf)
|
|
|
|
app := fiber.New()
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString("tls")
|
|
})
|
|
|
|
go func() {
|
|
assert.NoError(t, app.Listener(ln, fiber.ListenConfig{
|
|
DisableStartupMessage: true,
|
|
}))
|
|
}()
|
|
time.Sleep(1 * time.Second)
|
|
|
|
client := New()
|
|
resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String())
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, clientTLSConf, client.TLSConfig())
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "tls", resp.String())
|
|
}
|
|
|
|
func Test_Client_TLS_Error(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
serverTLSConf, clientTLSConf, err := tlstest.GetTLSConfigs()
|
|
clientTLSConf.MaxVersion = tls.VersionTLS12
|
|
serverTLSConf.MinVersion = tls.VersionTLS13
|
|
require.NoError(t, err)
|
|
|
|
ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
|
|
ln = tls.NewListener(ln, serverTLSConf)
|
|
|
|
app := fiber.New()
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString("tls")
|
|
})
|
|
|
|
go func() {
|
|
assert.NoError(t, app.Listener(ln, fiber.ListenConfig{
|
|
DisableStartupMessage: true,
|
|
}))
|
|
}()
|
|
time.Sleep(1 * time.Second)
|
|
|
|
client := New()
|
|
resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String())
|
|
|
|
require.Error(t, err)
|
|
require.Equal(t, clientTLSConf, client.TLSConfig())
|
|
require.Nil(t, resp)
|
|
}
|
|
|
|
func Test_Client_TLS_Empty_TLSConfig(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
serverTLSConf, clientTLSConf, err := tlstest.GetTLSConfigs()
|
|
require.NoError(t, err)
|
|
|
|
ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
|
|
ln = tls.NewListener(ln, serverTLSConf)
|
|
|
|
app := fiber.New()
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString("tls")
|
|
})
|
|
|
|
go func() {
|
|
assert.NoError(t, app.Listener(ln, fiber.ListenConfig{
|
|
DisableStartupMessage: true,
|
|
}))
|
|
}()
|
|
time.Sleep(1 * time.Second)
|
|
|
|
client := New()
|
|
resp, err := client.Get("https://" + ln.Addr().String())
|
|
|
|
require.Error(t, err)
|
|
require.NotEqual(t, clientTLSConf, client.TLSConfig())
|
|
require.Nil(t, resp)
|
|
}
|
|
|
|
func Test_Client_SetCertificates(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
serverTLSConf, _, err := tlstest.GetTLSConfigs()
|
|
require.NoError(t, err)
|
|
|
|
client := New().SetCertificates(serverTLSConf.Certificates...)
|
|
require.Len(t, client.TLSConfig().Certificates, 1)
|
|
}
|
|
|
|
func Test_Client_SetRootCertificate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
client := New().SetRootCertificate("../.github/testdata/ssl.pem")
|
|
require.NotNil(t, client.TLSConfig().RootCAs)
|
|
}
|
|
|
|
func Test_Client_SetRootCertificateFromString(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
file, err := os.Open("../.github/testdata/ssl.pem")
|
|
defer func() { require.NoError(t, file.Close()) }()
|
|
require.NoError(t, err)
|
|
|
|
pem, err := io.ReadAll(file)
|
|
require.NoError(t, err)
|
|
|
|
client := New().SetRootCertificateFromString(string(pem))
|
|
require.NotNil(t, client.TLSConfig().RootCAs)
|
|
}
|
|
|
|
func Test_Client_R(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
client := New()
|
|
req := client.R()
|
|
|
|
require.Equal(t, "Request", reflect.TypeOf(req).Elem().Name())
|
|
require.Equal(t, client, req.Client())
|
|
}
|
|
|
|
func Test_Replace(t *testing.T) {
|
|
app, dial, start := createHelperServer(t)
|
|
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString(string(c.Request().Header.Peek("k1")))
|
|
})
|
|
|
|
go start()
|
|
|
|
C().SetDial(dial)
|
|
resp, err := Get("http://example.com")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "", resp.String())
|
|
|
|
r := New().SetDial(dial).SetHeader("k1", "v1")
|
|
clean := Replace(r)
|
|
resp, err = Get("http://example.com")
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "v1", resp.String())
|
|
|
|
clean()
|
|
|
|
C().SetDial(dial)
|
|
resp, err = Get("http://example.com")
|
|
|
|
require.NoError(t, err)
|
|
require.Equal(t, fiber.StatusOK, resp.StatusCode())
|
|
require.Equal(t, "", resp.String())
|
|
|
|
C().SetDial(nil)
|
|
}
|
|
|
|
func Test_Set_Config_To_Request(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("set ctx", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
type ctxKey struct{}
|
|
var key ctxKey = struct{}{}
|
|
|
|
ctx := context.Background()
|
|
ctx = context.WithValue(ctx, key, "v1")
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{Ctx: ctx})
|
|
|
|
require.Equal(t, "v1", req.Context().Value(key))
|
|
})
|
|
|
|
t.Run("set useragent", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{UserAgent: "agent"})
|
|
|
|
require.Equal(t, "agent", req.UserAgent())
|
|
})
|
|
|
|
t.Run("set referer", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{Referer: "referer"})
|
|
|
|
require.Equal(t, "referer", req.Referer())
|
|
})
|
|
|
|
t.Run("set header", func(t *testing.T) {
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{Header: map[string]string{
|
|
"k1": "v1",
|
|
}})
|
|
|
|
require.Equal(t, "v1", req.Header("k1")[0])
|
|
})
|
|
|
|
t.Run("set params", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{Param: map[string]string{
|
|
"k1": "v1",
|
|
}})
|
|
|
|
require.Equal(t, "v1", req.Param("k1")[0])
|
|
})
|
|
|
|
t.Run("set cookies", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{Cookie: map[string]string{
|
|
"k1": "v1",
|
|
}})
|
|
|
|
require.Equal(t, "v1", req.Cookie("k1"))
|
|
})
|
|
|
|
t.Run("set pathparam", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{PathParam: map[string]string{
|
|
"k1": "v1",
|
|
}})
|
|
|
|
require.Equal(t, "v1", req.PathParam("k1"))
|
|
})
|
|
|
|
t.Run("set timeout", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{Timeout: 1 * time.Second})
|
|
|
|
require.Equal(t, 1*time.Second, req.Timeout())
|
|
})
|
|
|
|
t.Run("set maxredirects", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{MaxRedirects: 1})
|
|
|
|
require.Equal(t, 1, req.MaxRedirects())
|
|
})
|
|
|
|
t.Run("set body", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{Body: "test"})
|
|
|
|
require.Equal(t, "test", req.body)
|
|
})
|
|
|
|
t.Run("set file", func(t *testing.T) {
|
|
t.Parallel()
|
|
req := AcquireRequest()
|
|
|
|
setConfigToRequest(req, Config{File: []*File{
|
|
{
|
|
name: "test",
|
|
path: "path",
|
|
},
|
|
}})
|
|
|
|
require.Equal(t, "path", req.File("test").path)
|
|
})
|
|
}
|
|
|
|
func Test_Client_SetProxyURL(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
app, dial, start := createHelperServer(t)
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString(c.Get("isProxy"))
|
|
})
|
|
|
|
go start()
|
|
|
|
fasthttpClient := &fasthttp.Client{
|
|
Dial: dial,
|
|
NoDefaultUserAgentHeader: true,
|
|
DisablePathNormalizing: true,
|
|
}
|
|
|
|
// Create a simple proxy sever
|
|
proxyServer := fiber.New()
|
|
|
|
proxyServer.Use("*", func(c fiber.Ctx) error {
|
|
req := fasthttp.AcquireRequest()
|
|
resp := fasthttp.AcquireResponse()
|
|
|
|
req.SetRequestURI(c.BaseURL())
|
|
req.Header.SetMethod(fasthttp.MethodGet)
|
|
|
|
c.Request().Header.VisitAll(func(key, value []byte) {
|
|
req.Header.AddBytesKV(key, value)
|
|
})
|
|
|
|
req.Header.Set("isProxy", "true")
|
|
|
|
if err := fasthttpClient.Do(req, resp); err != nil {
|
|
return err
|
|
}
|
|
|
|
c.Status(resp.StatusCode())
|
|
c.RequestCtx().SetBody(resp.Body())
|
|
|
|
return nil
|
|
})
|
|
|
|
addrChan := make(chan string)
|
|
go func() {
|
|
assert.NoError(t, proxyServer.Listen(":0", fiber.ListenConfig{
|
|
DisableStartupMessage: true,
|
|
ListenerAddrFunc: func(addr net.Addr) {
|
|
addrChan <- addr.String()
|
|
},
|
|
}))
|
|
}()
|
|
|
|
t.Cleanup(func() {
|
|
require.NoError(t, app.Shutdown())
|
|
})
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
client := New()
|
|
err := client.SetProxyURL(<-addrChan)
|
|
|
|
require.NoError(t, err)
|
|
|
|
resp, err := client.Get("http://localhost:3000")
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 200, resp.StatusCode())
|
|
require.Equal(t, "true", string(resp.Body()))
|
|
})
|
|
|
|
t.Run("error", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := New()
|
|
|
|
err := client.SetProxyURL(":this is not a proxy")
|
|
require.NoError(t, err)
|
|
|
|
_, err = client.Get("http://localhost:3000")
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func Test_Client_SetRetryConfig(t *testing.T) {
|
|
t.Parallel()
|
|
retryConfig := &retry.Config{
|
|
InitialInterval: 1 * time.Second,
|
|
MaxRetryCount: 3,
|
|
}
|
|
|
|
core, client, req := newCore(), New(), AcquireRequest()
|
|
req.SetURL("http://exampleretry.com")
|
|
client.SetRetryConfig(retryConfig)
|
|
_, err := core.execute(context.Background(), client, req)
|
|
|
|
require.Error(t, err)
|
|
require.Equal(t, retryConfig.InitialInterval, client.RetryConfig().InitialInterval)
|
|
require.Equal(t, retryConfig.MaxRetryCount, client.RetryConfig().MaxRetryCount)
|
|
}
|
|
|
|
func Benchmark_Client_Request(b *testing.B) {
|
|
app, dial, start := createHelperServer(b)
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString("hello world")
|
|
})
|
|
|
|
go start()
|
|
|
|
client := New().SetDial(dial)
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
var err error
|
|
var resp *Response
|
|
for i := 0; i < b.N; i++ {
|
|
resp, err = client.Get("http://example.com")
|
|
resp.Close()
|
|
}
|
|
require.NoError(b, err)
|
|
}
|
|
|
|
func Benchmark_Client_Request_Parallel(b *testing.B) {
|
|
app, dial, start := createHelperServer(b)
|
|
app.Get("/", func(c fiber.Ctx) error {
|
|
return c.SendString("hello world")
|
|
})
|
|
|
|
go start()
|
|
|
|
client := New().SetDial(dial)
|
|
|
|
b.ResetTimer()
|
|
b.ReportAllocs()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
var err error
|
|
var resp *Response
|
|
for pb.Next() {
|
|
resp, err = client.Get("http://example.com")
|
|
resp.Close()
|
|
}
|
|
require.NoError(b, err)
|
|
})
|
|
}
|