Fix for the X-Format header (#51)

This commit is contained in:
Paramtamtam 2022-01-28 12:53:35 +05:00 committed by GitHub
parent 0efbccbb18
commit 13e7a72790
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 74 additions and 101 deletions

View File

@ -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)

View File

@ -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{})),

View File

@ -8,7 +8,5 @@ import (
)
func TestLiveChecker_Check(t *testing.T) {
t.Parallel()
assert.NoError(t, checkers.NewLiveChecker().Check())
}

View File

@ -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")
}

View File

@ -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)

View File

@ -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{})

View File

@ -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")
}

View File

@ -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{})

View File

@ -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))

View File

@ -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))

View File

@ -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")
}

View File

@ -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
}

View File

@ -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{},

View File

@ -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")
}

View File

@ -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")
}

View File

@ -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")
}

View File

@ -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")
}

View File

@ -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")
}

View File

@ -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")
}

View File

@ -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() })
}

View File

@ -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())
}

View File

@ -8,8 +8,6 @@ import (
)
func TestProperties_Replaces(t *testing.T) {
t.Parallel()
props := tpl.Properties{
Code: "foo",
Message: "bar",

View File

@ -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 {

View File

@ -5,8 +5,6 @@ import (
)
func TestVersion(t *testing.T) {
t.Parallel()
for give, want := range map[string]string{
// without changes
"vvv": "vvv",

View File

@ -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