MIME ParseMediaType在多部分边界上失败。

huangapple go评论71阅读模式
英文:

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.

https://play.golang.org/p/xJWwBa_QiP

答案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.

huangapple
  • 本文由 发表于 2017年4月21日 03:01:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/43527820.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定