mirror of
https://github.com/tarampampam/error-pages.git
synced 2024-08-30 18:22:40 +00:00
Fix for the X-Format header (#51)
This commit is contained in:
parent
0efbccbb18
commit
13e7a72790
@ -12,8 +12,6 @@ import (
|
||||
)
|
||||
|
||||
func TestNewOSSignals(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
oss := breaker.NewOSSignals(context.Background())
|
||||
|
||||
gotSignal := make(chan os.Signal, 1)
|
||||
@ -35,8 +33,6 @@ func TestNewOSSignals(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewOSSignalCtxCancel(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
oss := breaker.NewOSSignals(ctx)
|
||||
|
@ -16,8 +16,6 @@ type httpClientFunc func(*http.Request) (*http.Response, error)
|
||||
func (f httpClientFunc) Do(req *http.Request) (*http.Response, error) { return f(req) }
|
||||
|
||||
func TestHealthChecker_CheckSuccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var httpMock httpClientFunc = func(req *http.Request) (*http.Response, error) {
|
||||
assert.Equal(t, http.MethodGet, req.Method)
|
||||
assert.Equal(t, "http://127.0.0.1:123/healthz", req.URL.String())
|
||||
@ -35,8 +33,6 @@ func TestHealthChecker_CheckSuccess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHealthChecker_CheckFail(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var httpMock httpClientFunc = func(req *http.Request) (*http.Response, error) {
|
||||
return &http.Response{
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
|
@ -8,7 +8,5 @@ import (
|
||||
)
|
||||
|
||||
func TestLiveChecker_Check(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert.NoError(t, checkers.NewLiveChecker().Check())
|
||||
}
|
||||
|
@ -3,7 +3,5 @@ package build_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -16,8 +16,6 @@ type fakeChecker struct{ err error }
|
||||
func (c *fakeChecker) Check(port uint16) error { return c.err }
|
||||
|
||||
func TestProperties(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cmd := healthcheck.NewCommand(&fakeChecker{err: nil})
|
||||
|
||||
assert.Equal(t, "healthcheck", cmd.Use)
|
||||
|
@ -9,8 +9,6 @@ import (
|
||||
)
|
||||
|
||||
func TestSubcommands(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cmd := cli.NewCommand("unit test")
|
||||
|
||||
cases := []struct {
|
||||
@ -31,8 +29,6 @@ func TestSubcommands(t *testing.T) {
|
||||
for _, tt := range cases {
|
||||
tt := tt
|
||||
t.Run(tt.giveName, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if _, exists := subcommands[tt.giveName]; !exists {
|
||||
assert.Failf(t, "command not found", "command [%s] was not found", tt.giveName)
|
||||
}
|
||||
@ -41,8 +37,6 @@ func TestSubcommands(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFlags(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cmd := cli.NewCommand("unit test")
|
||||
|
||||
cases := []struct {
|
||||
@ -59,8 +53,6 @@ func TestFlags(t *testing.T) {
|
||||
for _, tt := range cases {
|
||||
tt := tt
|
||||
t.Run(tt.giveName, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
flag := cmd.Flag(tt.giveName)
|
||||
|
||||
if flag == nil {
|
||||
@ -76,8 +68,6 @@ func TestFlags(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExecuting(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cmd := cli.NewCommand("unit test")
|
||||
cmd.SetArgs([]string{})
|
||||
|
||||
|
@ -3,7 +3,5 @@ package serve_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ import (
|
||||
)
|
||||
|
||||
func TestProperties(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cmd := version.NewCommand("")
|
||||
|
||||
assert.Equal(t, "version", cmd.Use)
|
||||
@ -20,8 +18,6 @@ func TestProperties(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCommandRun(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cmd := version.NewCommand("1.2.3@foobar")
|
||||
cmd.SetArgs([]string{})
|
||||
|
||||
|
@ -9,8 +9,6 @@ import (
|
||||
)
|
||||
|
||||
func TestFromYaml(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var cases = map[string]struct { //nolint:maligned
|
||||
giveYaml []byte
|
||||
giveEnv map[string]string
|
||||
@ -111,8 +109,6 @@ pages:
|
||||
|
||||
for name, tt := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if tt.giveEnv != nil {
|
||||
for key, value := range tt.giveEnv {
|
||||
assert.NoError(t, os.Setenv(key, value))
|
||||
|
2
internal/env/env_test.go
vendored
2
internal/env/env_test.go
vendored
@ -8,8 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func TestConstants(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert.Equal(t, "LISTEN_ADDR", string(ListenAddr))
|
||||
assert.Equal(t, "LISTEN_PORT", string(ListenPort))
|
||||
assert.Equal(t, "TEMPLATE_NAME", string(TemplateName))
|
||||
|
@ -3,7 +3,5 @@ package common_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing2(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
@ -17,28 +19,66 @@ const (
|
||||
)
|
||||
|
||||
func ClientWantFormat(ctx *fasthttp.RequestCtx) ContentType {
|
||||
var (
|
||||
ct = bytes.ToLower(ctx.Request.Header.ContentType())
|
||||
f = bytes.ToLower(ctx.Request.Header.Peek(FormatHeader)) // for the Ingress support
|
||||
)
|
||||
// parse "Content-Type" header (e.g.: `application/json;charset=UTF-8`)
|
||||
if ct := bytes.ToLower(ctx.Request.Header.ContentType()); len(ct) > 4 { //nolint:gomnd
|
||||
return mimeTypeToContentType(ct)
|
||||
}
|
||||
|
||||
// parse `X-Format` header (aka `Accept`) for the Ingress support
|
||||
// e.g.: `text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8`
|
||||
if h := bytes.ToLower(bytes.TrimSpace(ctx.Request.Header.Peek(FormatHeader))); len(h) > 2 { //nolint:gomnd,nestif
|
||||
type format struct {
|
||||
mimeType []byte
|
||||
weight float32
|
||||
}
|
||||
|
||||
var formats = make([]format, 0, 8) //nolint:gomnd
|
||||
|
||||
for _, b := range bytes.FieldsFunc(h, func(r rune) bool { return r == ',' }) {
|
||||
if idx := bytes.Index(b, []byte(";q=")); idx > 0 && idx < len(b) {
|
||||
f := format{b[0:idx], 0}
|
||||
|
||||
if len(b) > idx+3 {
|
||||
if weight, err := strconv.ParseFloat(string(b[idx+3:]), 32); err == nil { //nolint:gomnd
|
||||
f.weight = float32(weight)
|
||||
}
|
||||
}
|
||||
|
||||
formats = append(formats, f)
|
||||
} else {
|
||||
formats = append(formats, format{b, 1})
|
||||
}
|
||||
}
|
||||
|
||||
switch l := len(formats); {
|
||||
case l == 0:
|
||||
return UnknownContentType
|
||||
|
||||
case l == 1:
|
||||
return mimeTypeToContentType(formats[0].mimeType)
|
||||
|
||||
default:
|
||||
sort.SliceStable(formats, func(i, j int) bool { return formats[i].weight > formats[j].weight })
|
||||
|
||||
return mimeTypeToContentType(formats[0].mimeType)
|
||||
}
|
||||
}
|
||||
|
||||
return UnknownContentType
|
||||
}
|
||||
|
||||
func mimeTypeToContentType(mimeType []byte) ContentType {
|
||||
switch {
|
||||
case bytes.Contains(f, []byte("json")),
|
||||
bytes.Contains(ct, []byte("application/json")),
|
||||
bytes.Contains(ct, []byte("text/json")):
|
||||
case bytes.Contains(mimeType, []byte("application/json")), bytes.Contains(mimeType, []byte("text/json")):
|
||||
return JSONContentType
|
||||
|
||||
case bytes.Contains(f, []byte("xml")),
|
||||
bytes.Contains(ct, []byte("application/xml")),
|
||||
bytes.Contains(ct, []byte("text/xml")):
|
||||
case bytes.Contains(mimeType, []byte("application/xml")), bytes.Contains(mimeType, []byte("text/xml")):
|
||||
return XMLContentType
|
||||
|
||||
case bytes.Contains(f, []byte("html")),
|
||||
bytes.Contains(ct, []byte("text/html")):
|
||||
case bytes.Contains(mimeType, []byte("text/html")):
|
||||
return HTMLContentType
|
||||
|
||||
case bytes.Contains(f, []byte("plain")),
|
||||
bytes.Contains(ct, []byte("text/plain")):
|
||||
case bytes.Contains(mimeType, []byte("text/plain")):
|
||||
return PlainTextContentType
|
||||
}
|
||||
|
||||
|
@ -9,14 +9,26 @@ import (
|
||||
)
|
||||
|
||||
func TestClientWantFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for name, tt := range map[string]struct {
|
||||
giveContentTypeHeader string
|
||||
giveFormatHeader string
|
||||
giveReqCtx func() *fasthttp.RequestCtx
|
||||
wantFormat core.ContentType
|
||||
}{
|
||||
"priority": {
|
||||
giveFormatHeader: "application/xml",
|
||||
giveContentTypeHeader: "text/plain",
|
||||
wantFormat: core.PlainTextContentType,
|
||||
},
|
||||
"format respects weight": {
|
||||
giveFormatHeader: "text/html;q=0.5,application/xhtml+xml;q=0.9,application/xml;q=1,*/*;q=0.8",
|
||||
wantFormat: core.XMLContentType,
|
||||
},
|
||||
"wrong format value": {
|
||||
giveFormatHeader: ";q=foobar,bar/baz;;;;;application/xml",
|
||||
wantFormat: core.UnknownContentType,
|
||||
},
|
||||
|
||||
"content type - application/json": {
|
||||
giveContentTypeHeader: "application/jsoN; charset=utf-8", wantFormat: core.JSONContentType,
|
||||
},
|
||||
@ -24,7 +36,7 @@ func TestClientWantFormat(t *testing.T) {
|
||||
giveContentTypeHeader: "text/Json; charset=utf-8", wantFormat: core.JSONContentType,
|
||||
},
|
||||
"format - json": {
|
||||
giveFormatHeader: "jsOn", wantFormat: core.JSONContentType,
|
||||
giveFormatHeader: "application/jsoN,*/*;q=0.8", wantFormat: core.JSONContentType,
|
||||
},
|
||||
|
||||
"content type - application/xml": {
|
||||
@ -34,21 +46,22 @@ func TestClientWantFormat(t *testing.T) {
|
||||
giveContentTypeHeader: "text/Xml; charset=utf-8", wantFormat: core.XMLContentType,
|
||||
},
|
||||
"format - xml": {
|
||||
giveFormatHeader: "xMl", wantFormat: core.XMLContentType,
|
||||
giveFormatHeader: "text/Xml", wantFormat: core.XMLContentType,
|
||||
},
|
||||
|
||||
"content type - text/html": {
|
||||
giveContentTypeHeader: "text/htMl; charset=utf-8", wantFormat: core.HTMLContentType,
|
||||
},
|
||||
"format - html": {
|
||||
giveFormatHeader: "HtmL", wantFormat: core.HTMLContentType,
|
||||
giveFormatHeader: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||
wantFormat: core.HTMLContentType,
|
||||
},
|
||||
|
||||
"content type - text/plain": {
|
||||
giveContentTypeHeader: "text/plaiN; charset=utf-8", wantFormat: core.PlainTextContentType,
|
||||
},
|
||||
"format - plain": {
|
||||
giveFormatHeader: "PLAIN", wantFormat: core.PlainTextContentType,
|
||||
giveFormatHeader: "text/plaiN,text/html,application/xml;q=0.9,,,*/*;q=0.8", wantFormat: core.PlainTextContentType,
|
||||
},
|
||||
|
||||
"unknown on empty": {
|
||||
@ -61,8 +74,6 @@ func TestClientWantFormat(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
h := &fasthttp.RequestHeader{}
|
||||
h.Set(fasthttp.HeaderContentType, tt.giveContentTypeHeader)
|
||||
h.Set(core.FormatHeader, tt.giveFormatHeader)
|
||||
@ -79,8 +90,6 @@ func TestClientWantFormat(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSetClientFormat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for name, tt := range map[string]struct {
|
||||
giveContentType core.ContentType
|
||||
wantHeaderValue string
|
||||
@ -92,8 +101,6 @@ func TestSetClientFormat(t *testing.T) {
|
||||
"plain": {giveContentType: core.PlainTextContentType, wantHeaderValue: "text/plain; charset=utf-8"},
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := &fasthttp.RequestCtx{
|
||||
Response: fasthttp.Response{
|
||||
Header: fasthttp.ResponseHeader{},
|
||||
|
@ -3,7 +3,5 @@ package errorpage_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -3,7 +3,5 @@ package healthz_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -3,7 +3,5 @@ package index_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -3,7 +3,5 @@ package notfound_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -3,7 +3,5 @@ package version_test
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -3,7 +3,5 @@ package http
|
||||
import "testing"
|
||||
|
||||
func TestNothing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Skip("tests for this package have not been implemented yet")
|
||||
}
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func TestPicker_NextIndex_First(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for i := uint32(0); i < 100; i++ {
|
||||
p := pick.NewPicker(i, pick.First)
|
||||
|
||||
@ -20,8 +18,6 @@ func TestPicker_NextIndex_First(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPicker_NextIndex_RandomOnce(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for i := uint8(0); i < 10; i++ {
|
||||
assert.Equal(t, uint32(0), pick.NewPicker(0, pick.RandomOnce).NextIndex())
|
||||
}
|
||||
@ -39,8 +35,6 @@ func TestPicker_NextIndex_RandomOnce(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPicker_NextIndex_RandomEveryTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for i := uint8(0); i < 10; i++ {
|
||||
assert.Equal(t, uint32(0), pick.NewPicker(0, pick.RandomEveryTime).NextIndex())
|
||||
}
|
||||
@ -59,7 +53,5 @@ func TestPicker_NextIndex_RandomEveryTime(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPicker_NextIndex_Unsupported(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert.Panics(t, func() { pick.NewPicker(1, 255).NextIndex() })
|
||||
}
|
||||
|
@ -8,11 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func TestStringsSlice_Pick(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("first", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for i := uint8(0); i < 100; i++ {
|
||||
assert.Equal(t, "", pick.NewStringsSlice([]string{}, pick.First).Pick())
|
||||
}
|
||||
@ -25,8 +21,6 @@ func TestStringsSlice_Pick(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("random once", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for i := uint8(0); i < 100; i++ {
|
||||
assert.Equal(t, "", pick.NewStringsSlice([]string{}, pick.RandomOnce).Pick())
|
||||
}
|
||||
@ -42,8 +36,6 @@ func TestStringsSlice_Pick(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("random every time", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for i := uint8(0); i < 100; i++ {
|
||||
assert.Equal(t, "", pick.NewStringsSlice([]string{}, pick.RandomEveryTime).Pick())
|
||||
}
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func TestProperties_Replaces(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
props := tpl.Properties{
|
||||
Code: "foo",
|
||||
Message: "bar",
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func Test_Render(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for name, tt := range map[string]struct {
|
||||
giveContent string
|
||||
giveProps tpl.Properties
|
||||
@ -54,8 +52,6 @@ func Test_Render(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
content, err := tpl.Render([]byte(tt.giveContent), tt.giveProps)
|
||||
|
||||
if tt.wantError == true {
|
||||
|
@ -5,8 +5,6 @@ import (
|
||||
)
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for give, want := range map[string]string{
|
||||
// without changes
|
||||
"vvv": "vvv",
|
||||
|
@ -13,7 +13,7 @@ body contains "Gone"
|
||||
# X-Code with X-Format
|
||||
GET http://{{ host }}:{{ port }}/
|
||||
X-Code: 410
|
||||
X-Format: text/json
|
||||
X-Format: text/html;q=0.9,application/xhtml+xml;q=0.9,application/json,image/avif,image/webp,*/*;q=0.8
|
||||
|
||||
HTTP/* 410
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user