aboutsummaryrefslogtreecommitdiff
path: root/header_test.go
diff options
context:
space:
mode:
authorGravatar nickajacks1 <128185314+nickajacks1@users.noreply.github.com> 2024-01-02 00:43:40 -0800
committerGravatar GitHub <noreply@github.com> 2024-01-02 09:43:40 +0100
commit868ee455d5f9b5ffebae03906d581eb360f5d835 (patch)
treed1aa9e56bfc7141ef1d9ccdd911ef03c269d26ef /header_test.go
parentchore(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#1678) (diff)
downloadfasthttp-868ee455d5f9b5ffebae03906d581eb360f5d835.tar.gz
fasthttp-868ee455d5f9b5ffebae03906d581eb360f5d835.tar.bz2
fasthttp-868ee455d5f9b5ffebae03906d581eb360f5d835.zip
feat: add function to parse HTTP header parameters (#1685)
* feat: add function to parse HTTP header parameters The implementation is based on RFC-9110 5.6.6. * test: add fuzz for VisitHeaderParams
Diffstat (limited to 'header_test.go')
-rw-r--r--header_test.go69
1 files changed, 69 insertions, 0 deletions
diff --git a/header_test.go b/header_test.go
index 2893751..eaa9a50 100644
--- a/header_test.go
+++ b/header_test.go
@@ -1061,6 +1061,75 @@ func testRequestHeaderHasAcceptEncoding(t *testing.T, ae, v string, resultExpect
}
}
+func TestVisitHeaderParams(t *testing.T) {
+ t.Parallel()
+ testVisitHeaderParams(t, "text/plain;charset=utf-8;q=0.39", [][2]string{{"charset", "utf-8"}, {"q", "0.39"}})
+ testVisitHeaderParams(t, "text/plain; foo=bar ;", [][2]string{{"foo", "bar"}})
+ testVisitHeaderParams(t, `text/plain; foo="bar"; `, [][2]string{{"foo", "bar"}})
+ testVisitHeaderParams(t, `text/plain; foo="text/plain,text/html;charset=\"utf-8\""`, [][2]string{{"foo", `text/plain,text/html;charset=\"utf-8\"`}})
+ testVisitHeaderParams(t, "text/plain foo=bar", [][2]string{})
+ testVisitHeaderParams(t, "text/plain;", [][2]string{})
+ testVisitHeaderParams(t, "text/plain; ", [][2]string{})
+ testVisitHeaderParams(t, "text/plain; foo", [][2]string{})
+ testVisitHeaderParams(t, "text/plain; foo=", [][2]string{})
+ testVisitHeaderParams(t, "text/plain; =bar", [][2]string{})
+ testVisitHeaderParams(t, "text/plain; foo = bar", [][2]string{})
+ testVisitHeaderParams(t, `text/plain; foo="bar`, [][2]string{})
+ testVisitHeaderParams(t, "text/plain;;foo=bar", [][2]string{})
+
+ parsed := make([][2]string, 0)
+ VisitHeaderParams([]byte(`text/plain; foo=bar; charset=utf-8`), func(key, value []byte) bool {
+ parsed = append(parsed, [2]string{string(key), string(value)})
+ return !bytes.Equal(key, []byte("foo"))
+ })
+
+ if len(parsed) != 1 {
+ t.Fatalf("expected 1 HTTP parameter, parsed %v", len(parsed))
+ }
+
+ if parsed[0] != [2]string{"foo", "bar"} {
+ t.Fatalf("unexpected parameter %v=%v. Expecting foo=bar", parsed[0][0], parsed[0][1])
+ }
+}
+
+func testVisitHeaderParams(t *testing.T, header string, expectedParams [][2]string) {
+ parsed := make([][2]string, 0)
+ VisitHeaderParams([]byte(header), func(key, value []byte) bool {
+ parsed = append(parsed, [2]string{string(key), string(value)})
+ return true
+ })
+
+ if len(parsed) != len(expectedParams) {
+ t.Fatalf("expected %v HTTP parameters, parsed %v", len(expectedParams), len(parsed))
+ }
+
+ for i := range expectedParams {
+ if expectedParams[i] != parsed[i] {
+ t.Fatalf("unexpected parameter %v=%v. Expecting %v=%v", parsed[i][0], parsed[i][1], expectedParams[i][0], expectedParams[i][1])
+ }
+ }
+}
+
+func FuzzVisitHeaderParams(f *testing.F) {
+ inputs := []string{
+ `application/json; v=1; foo=bar; q=0.938; param=param; param="big fox"; q=0.43`,
+ `*/*`,
+ `\\`,
+ `text/plain; foo="\\\"\'\\''\'"`,
+ }
+ for _, input := range inputs {
+ f.Add([]byte(input))
+ }
+ f.Fuzz(func(t *testing.T, header []byte) {
+ VisitHeaderParams(header, func(key, value []byte) bool {
+ if len(key) == 0 {
+ t.Errorf("Unexpected length zero parameter, failed input was: %s", header)
+ }
+ return true
+ })
+ })
+}
+
func TestRequestMultipartFormBoundary(t *testing.T) {
t.Parallel()