I am a Golang api that accept multipart/form-data requests. For some clients, however, it fails to parse the form because it doesn't like the boundary being used by the client.
The header from the client is:
Content-Type:[multipart/form-data; boundary================1648430772==]
I've narrowed this down to the ParseMediaType
function in the mime
package.
If I call:
bad := "multipart/form-data; boundary=1650458473"
d, params, err := mime.ParseMediaType(v)
if err != nil {
fmt.Println("err", err)
}
fmt.Println(d, params)
I get the err: mime: invalid media parameter
.
Note that if I do this call with
multipart/form-data; boundary=3fc88aad6d1341a4921fd5ac9efe607c
it succeeds no problem.
According to the https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html spec, it looks to me like these are all valid characters for a boundary.
Is this a bug in the Go mime library? Or is this really an invalid boundary?
The rfc you linked to contains BNF for the boundary and multipart body, it does not contain the BNF for the Content-Type Header Field. So while =
in boundary is just fine it's not fine in the parameter
value
of the Content-Type
header. At least not unquoted.
So to fix your first example change the Content-Type to this:
multipart/form-data; boundary="===============1648430772=="
https://play.golang.org/p/3Iuk_ACZaQ
Your second example multipart/form-data; boundary=1650458473
seems to work fine.
Finally found the answer. In the RFC 2045 doc (https://www.ietf.org/rfc/rfc2045.txt) it states that certain values cannot be used as parameter values in the Content-Type
header.
The pertinent section:
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
So you can use an equal sign, but only if it's quoted, so Go fails on the parsing. The client in this case is sending a technically-incorrect value for the boundary
param.