英文:
MIME ParseMediaType fails on multipart boundary
问题
我是一个接受multipart/form-data请求的Golang API。然而,对于某些客户端,它无法解析表单,因为它不喜欢客户端使用的boundary。
客户端的头部信息是:
Content-Type:[multipart/form-data; boundary================1648430772==]
我已经将问题缩小到了mime
包中的ParseMediaType
函数。
如果我调用:
bad := "multipart/form-data; boundary=1650458473"
d, params, err := mime.ParseMediaType(v)
if err != nil {
fmt.Println("err", err)
}
fmt.Println(d, params)
我会得到错误:mime: invalid media parameter
。
请注意,如果我使用以下方式调用:
multipart/form-data; boundary=3fc88aad6d1341a4921fd5ac9efe607c
它会成功,没有问题。
根据https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html规范,我认为这些都是有效的boundary字符。
这是Go mime库的一个bug吗?还是这个boundary确实是无效的?
英文:
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?
答案1
得分: 3
你链接的rfc中包含了边界和多部分主体的BNF,但没有包含Content-Type Header Field的BNF。所以,虽然边界中的=
是可以的,但在Content-Type
头部的parameter
value
中是不可以的,至少不能不加引号。
所以,要修复你的第一个示例,将Content-Type更改为以下内容:
multipart/form-data; boundary="===============1648430772=="
你的第二个示例multipart/form-data; boundary=1650458473
似乎工作正常。
英文:
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.
答案2
得分: 0
终于找到答案了。在 RFC 2045 文档(https://www.ietf.org/rfc/rfc2045.txt)中指出,在 Content-Type
头中,某些值不能用作参数值。
相关部分如下:
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; 必须在引号中使用,
; 以在参数值中使用
因此,你可以使用等号,但只有在引号中使用,所以 Go 在解析时失败了。在这种情况下,客户端发送了一个技术上不正确的值作为 boundary
参数。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论