162 lines
3.8 KiB
Go
162 lines
3.8 KiB
Go
|
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)
|
||
|
}
|
||
|
}
|
||
|
}
|