package v2 import ( "testing" ) func TestParseForwardedHeader(t *testing.T) { for _, tc := range []struct { name string raw string expected map[string]string expectedRest string expectedError bool }{ { name: "empty", raw: "", }, { name: "one pair", raw: " key = value ", expected: map[string]string{"key": "value"}, }, { name: "two pairs", raw: " key1 = value1; key2=value2", expected: map[string]string{"key1": "value1", "key2": "value2"}, }, { name: "uppercase parameter", raw: "KeY=VaL", expected: map[string]string{"key": "VaL"}, }, { name: "missing key=value pair - be tolerant", raw: "key=val;", expected: map[string]string{"key": "val"}, }, { name: "quoted values", raw: `key="val";param = "[[ $((1 + 1)) == 3 ]] && echo panic!;" ; p=" abcd "`, expected: map[string]string{"key": "val", "param": "[[ $((1 + 1)) == 3 ]] && echo panic!;", "p": " abcd "}, }, { name: "empty quoted value", raw: `key=""`, expected: map[string]string{"key": ""}, }, { name: "quoted double quotes", raw: `key="\"value\""`, expected: map[string]string{"key": `"value"`}, }, { name: "quoted backslash", raw: `key="\"\\\""`, expected: map[string]string{"key": `"\"`}, }, { name: "ignore subsequent elements", raw: "key=a, param= b", expected: map[string]string{"key": "a"}, expectedRest: " param= b", }, { name: "empty element - be tolerant", raw: " , key=val", expectedRest: " key=val", }, { name: "obscure key", raw: `ob₷C&r€ = value`, expected: map[string]string{`ob₷c&r€`: "value"}, }, { name: "duplicate parameter", raw: "key=a; p=b; key=c", expectedError: true, }, { name: "empty parameter", raw: "=value", expectedError: true, }, { name: "empty value", raw: "key= ", expectedError: true, }, { name: "empty value before a new element ", raw: "key=,", expectedError: true, }, { name: "empty value before a new pair", raw: "key=;", expectedError: true, }, { name: "just parameter", raw: "key", expectedError: true, }, { name: "missing key-value", raw: "a=b;;", expectedError: true, }, { name: "unclosed quoted value", raw: `key="value`, expectedError: true, }, { name: "escaped terminating dquote", raw: `key="value\"`, expectedError: true, }, { name: "just a quoted value", raw: `"key=val"`, expectedError: true, }, { name: "quoted key", raw: `"key"=val`, expectedError: true, }, } { parsed, rest, err := parseForwardedHeader(tc.raw) if err != nil && !tc.expectedError { t.Errorf("[%s] got unexpected error: %v", tc.name, err) } if err == nil && tc.expectedError { t.Errorf("[%s] got unexpected non-error", tc.name) } if err != nil || tc.expectedError { continue } for key, value := range tc.expected { v, exists := parsed[key] if !exists { t.Errorf("[%s] missing expected parameter %q", tc.name, key) continue } if v != value { t.Errorf("[%s] got unexpected value for parameter %q: %q != %q", tc.name, key, v, value) } } for key, value := range parsed { if _, exists := tc.expected[key]; !exists { t.Errorf("[%s] got unexpected key/value pair: %q=%q", tc.name, key, value) } } if rest != tc.expectedRest { t.Errorf("[%s] got unexpected unparsed string: %q != %q", tc.name, rest, tc.expectedRest) } } }