mirror of
https://github.com/gofiber/fiber.git
synced 2025-02-06 23:31:55 +00:00
2768ea2a77
Co-Authored-By: RW <7063188+ReneWerner87@users.noreply.github.com>
303 lines
7.9 KiB
Go
303 lines
7.9 KiB
Go
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
|
|
// 📝 Github Repository: https://github.com/gofiber/fiber
|
|
// 📌 API Documentation: https://docs.gofiber.io
|
|
|
|
package fiber
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v2/utils"
|
|
"github.com/valyala/fasthttp"
|
|
)
|
|
|
|
// go test -v -run=^$ -bench=Benchmark_Utils_RemoveNewLines -benchmem -count=4
|
|
func Benchmark_Utils_RemoveNewLines(b *testing.B) {
|
|
withNL := "foo\r\nSet-Cookie:%20SESSIONID=MaliciousValue\r\n"
|
|
withoutNL := "foo Set-Cookie:%20SESSIONID=MaliciousValue "
|
|
expected := utils.ImmutableString(withoutNL)
|
|
var res string
|
|
|
|
b.Run("withNewlines", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for n := 0; n < b.N; n++ {
|
|
res = removeNewLines(withNL)
|
|
}
|
|
utils.AssertEqual(b, expected, res)
|
|
})
|
|
b.Run("withoutNewlines", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
b.ResetTimer()
|
|
for n := 0; n < b.N; n++ {
|
|
res = removeNewLines(withoutNL)
|
|
}
|
|
utils.AssertEqual(b, expected, res)
|
|
})
|
|
|
|
}
|
|
|
|
// go test -v -run=Test_Utils_ -count=3
|
|
func Test_Utils_ETag(t *testing.T) {
|
|
app := New()
|
|
t.Run("Not Status OK", func(t *testing.T) {
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
c.Status(201)
|
|
setETag(c, false)
|
|
utils.AssertEqual(t, "", string(c.Response().Header.Peek(HeaderETag)))
|
|
})
|
|
|
|
t.Run("No Body", func(t *testing.T) {
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
setETag(c, false)
|
|
utils.AssertEqual(t, "", string(c.Response().Header.Peek(HeaderETag)))
|
|
})
|
|
|
|
t.Run("Has HeaderIfNoneMatch", func(t *testing.T) {
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
c.Request().Header.Set(HeaderIfNoneMatch, `"13-1831710635"`)
|
|
setETag(c, false)
|
|
utils.AssertEqual(t, 304, c.Response().StatusCode())
|
|
utils.AssertEqual(t, "", string(c.Response().Header.Peek(HeaderETag)))
|
|
utils.AssertEqual(t, "", string(c.Response().Body()))
|
|
})
|
|
|
|
t.Run("No HeaderIfNoneMatch", func(t *testing.T) {
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
setETag(c, false)
|
|
utils.AssertEqual(t, `"13-1831710635"`, string(c.Response().Header.Peek(HeaderETag)))
|
|
})
|
|
}
|
|
|
|
// go test -v -run=^$ -bench=Benchmark_App_ETag -benchmem -count=4
|
|
func Benchmark_Utils_ETag(b *testing.B) {
|
|
app := New()
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
for n := 0; n < b.N; n++ {
|
|
setETag(c, false)
|
|
}
|
|
utils.AssertEqual(b, `"13-1831710635"`, string(c.Response().Header.Peek(HeaderETag)))
|
|
}
|
|
|
|
// go test -v -run=Test_Utils_ETag_Weak -count=1
|
|
func Test_Utils_ETag_Weak(t *testing.T) {
|
|
app := New()
|
|
t.Run("Set Weak", func(t *testing.T) {
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
setETag(c, true)
|
|
utils.AssertEqual(t, `W/"13-1831710635"`, string(c.Response().Header.Peek(HeaderETag)))
|
|
})
|
|
|
|
t.Run("Match Weak ETag", func(t *testing.T) {
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
c.Request().Header.Set(HeaderIfNoneMatch, `W/"13-1831710635"`)
|
|
setETag(c, true)
|
|
utils.AssertEqual(t, 304, c.Response().StatusCode())
|
|
utils.AssertEqual(t, "", string(c.Response().Header.Peek(HeaderETag)))
|
|
utils.AssertEqual(t, "", string(c.Response().Body()))
|
|
})
|
|
|
|
t.Run("Not Match Weak ETag", func(t *testing.T) {
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
c.Request().Header.Set(HeaderIfNoneMatch, `W/"13-1831710635xx"`)
|
|
setETag(c, true)
|
|
utils.AssertEqual(t, `W/"13-1831710635"`, string(c.Response().Header.Peek(HeaderETag)))
|
|
})
|
|
}
|
|
|
|
func Test_Utils_UniqueRouteStack(t *testing.T) {
|
|
route1 := &Route{}
|
|
route2 := &Route{}
|
|
route3 := &Route{}
|
|
utils.AssertEqual(
|
|
t,
|
|
[]*Route{
|
|
route1,
|
|
route2,
|
|
route3,
|
|
},
|
|
uniqueRouteStack([]*Route{
|
|
route1,
|
|
route1,
|
|
route1,
|
|
route2,
|
|
route2,
|
|
route2,
|
|
route3,
|
|
route3,
|
|
route3,
|
|
route1,
|
|
route2,
|
|
route3,
|
|
}),
|
|
)
|
|
}
|
|
|
|
// go test -v -run=^$ -bench=Benchmark_App_ETag_Weak -benchmem -count=4
|
|
func Benchmark_Utils_ETag_Weak(b *testing.B) {
|
|
app := New()
|
|
c := app.AcquireCtx(&fasthttp.RequestCtx{})
|
|
defer app.ReleaseCtx(c)
|
|
c.SendString("Hello, World!")
|
|
for n := 0; n < b.N; n++ {
|
|
setETag(c, true)
|
|
}
|
|
utils.AssertEqual(b, `W/"13-1831710635"`, string(c.Response().Header.Peek(HeaderETag)))
|
|
}
|
|
|
|
func Test_Utils_getGroupPath(t *testing.T) {
|
|
t.Parallel()
|
|
res := getGroupPath("/v1", "/")
|
|
utils.AssertEqual(t, "/v1", res)
|
|
|
|
res = getGroupPath("/v1/", "/")
|
|
utils.AssertEqual(t, "/v1/", res)
|
|
|
|
res = getGroupPath("/v1", "/")
|
|
utils.AssertEqual(t, "/v1", res)
|
|
|
|
res = getGroupPath("/", "/")
|
|
utils.AssertEqual(t, "/", res)
|
|
|
|
res = getGroupPath("/v1/api/", "/")
|
|
utils.AssertEqual(t, "/v1/api/", res)
|
|
}
|
|
|
|
// go test -v -run=^$ -bench=Benchmark_Utils_ -benchmem -count=3
|
|
|
|
func Benchmark_Utils_getGroupPath(b *testing.B) {
|
|
var res string
|
|
for n := 0; n < b.N; n++ {
|
|
_ = getGroupPath("/v1/long/path/john/doe", "/why/this/name/is/so/awesome")
|
|
_ = getGroupPath("/v1", "/")
|
|
_ = getGroupPath("/v1", "/api")
|
|
res = getGroupPath("/v1", "/api/register/:project")
|
|
}
|
|
utils.AssertEqual(b, "/v1/api/register/:project", res)
|
|
}
|
|
|
|
func Benchmark_Utils_Unescape(b *testing.B) {
|
|
unescaped := ""
|
|
dst := make([]byte, 0)
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
source := "/cr%C3%A9er"
|
|
pathBytes := getBytes(source)
|
|
pathBytes = fasthttp.AppendUnquotedArg(dst[:0], pathBytes)
|
|
unescaped = getString(pathBytes)
|
|
}
|
|
|
|
utils.AssertEqual(b, "/créer", unescaped)
|
|
}
|
|
|
|
func Test_Utils_IPv6(t *testing.T) {
|
|
testCases := []struct {
|
|
string
|
|
bool
|
|
}{
|
|
{"::FFFF:C0A8:1:3000", true},
|
|
{"::FFFF:C0A8:0001:3000", true},
|
|
{"0000:0000:0000:0000:0000:FFFF:C0A8:1:3000", true},
|
|
{"::FFFF:C0A8:1%1:3000", true},
|
|
{"::FFFF:192.168.0.1:3000", true},
|
|
{"[::FFFF:C0A8:1]:3000", true},
|
|
{"[::FFFF:C0A8:1%1]:3000", true},
|
|
{":3000", false},
|
|
{"127.0.0.1:3000", false},
|
|
{"127.0.0.1:", false},
|
|
{"0.0.0.0:3000", false},
|
|
{"", false},
|
|
}
|
|
|
|
for _, c := range testCases {
|
|
utils.AssertEqual(t, c.bool, isIPv6(c.string))
|
|
}
|
|
}
|
|
|
|
func Test_Utils_Parse_Address(t *testing.T) {
|
|
testCases := []struct {
|
|
addr, host, port string
|
|
}{
|
|
{"[::]:3000", "[::]", "3000"},
|
|
{"127.0.0.1:3000", "127.0.0.1", "3000"},
|
|
{"/path/to/unix/socket", "/path/to/unix/socket", ""},
|
|
}
|
|
|
|
for _, c := range testCases {
|
|
host, port := parseAddr(c.addr)
|
|
utils.AssertEqual(t, c.host, host, "addr host")
|
|
utils.AssertEqual(t, c.port, port, "addr port")
|
|
}
|
|
}
|
|
|
|
func Test_Utils_GetOffset(t *testing.T) {
|
|
utils.AssertEqual(t, "", getOffer("hello"))
|
|
utils.AssertEqual(t, "1", getOffer("", "1"))
|
|
utils.AssertEqual(t, "", getOffer("2", "1"))
|
|
}
|
|
|
|
func Test_Utils_TestAddr_Network(t *testing.T) {
|
|
var addr testAddr = "addr"
|
|
utils.AssertEqual(t, "addr", addr.Network())
|
|
}
|
|
|
|
func Test_Utils_TestConn_Deadline(t *testing.T) {
|
|
conn := &testConn{}
|
|
utils.AssertEqual(t, nil, conn.SetDeadline(time.Time{}))
|
|
utils.AssertEqual(t, nil, conn.SetReadDeadline(time.Time{}))
|
|
utils.AssertEqual(t, nil, conn.SetWriteDeadline(time.Time{}))
|
|
}
|
|
|
|
func Test_Utils_IsNoCache(t *testing.T) {
|
|
testCases := []struct {
|
|
string
|
|
bool
|
|
}{
|
|
{"public", false},
|
|
{"no-cache", true},
|
|
{"public, no-cache, max-age=30", true},
|
|
{"public,no-cache", true},
|
|
{"public,no-cacheX", false},
|
|
{"no-cache, public", true},
|
|
{"Xno-cache, public", false},
|
|
{"max-age=30, no-cache,public", true},
|
|
}
|
|
|
|
for _, c := range testCases {
|
|
ok := isNoCache(c.string)
|
|
utils.AssertEqual(t, c.bool, ok,
|
|
fmt.Sprintf("want %t, got isNoCache(%s)=%t", c.bool, c.string, ok))
|
|
}
|
|
}
|
|
|
|
// go test -v -run=^$ -bench=Benchmark_Utils_IsNoCache -benchmem -count=4
|
|
func Benchmark_Utils_IsNoCache(b *testing.B) {
|
|
var ok bool
|
|
for i := 0; i < b.N; i++ {
|
|
ok = isNoCache("public")
|
|
ok = isNoCache("no-cache")
|
|
ok = isNoCache("public, no-cache, max-age=30")
|
|
ok = isNoCache("public,no-cache")
|
|
ok = isNoCache("no-cache, public")
|
|
ok = isNoCache("max-age=30, no-cache,public")
|
|
}
|
|
utils.AssertEqual(b, true, ok)
|
|
}
|