Unable to use list<X> in a HTTP query parameter results in panic
jacobgreenleaf opened this issue · comments
When decoding URI parameters for HTTP requests, zanzibar lacks an encoder and decoder for list Thrift types, e.g. list<string>
. Currently this causes a panic due to a failing type switch when trying to create the encoder or decoder.
A standard encoding of composite types is undefined. RFC 3986 § 3.4 merely says:
[...] query components are often used to carry identifying information in the form of "key=value" pairs
but defines no convention for delimiters or encodings of complex types like maps or lists, leaving it up to the particular HTTP daemon to decide.
Golang net
standard library will encode a list e.g. foo=[a, b]
as foo=a&foo=b
:
v := url.Values{}
v.Set("name", "Ava")
v.Add("friend", "Jess")
v.Add("friend", "Sarah")
v.Add("friend", "Zoe")
// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"
Decoding is done by using the map access since url.Values
is typedef of a map[string][]string
.
Zanzibar has support for struct types in URL parameters by using a dotted notation: a.b=foo
would map b
as a string property on struct a
. This creates ambiguity if we add support for list types; a.b.c=foo&a.b.c=bar
can be decoded to either of these structs:
As c
is list of string:
struct A {
1: required B b
}
struct B {
1: required list<string> c
}
Or as b
is list of struct:
struct A {
1: required list<B> b
}
struct B {
1: required string c
}
To avoid this ambiguity, we should restrict lists to scalar types.