Firefox 实现 NPAPI 时的一个 BUG

在 NPAPI 里有一个接口 NPN_PostURL(),可以用来控制浏览器做 HTTP POST,
接口是这样的:

NPError NPN_PostURL(NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file);
可以看出来,这个接口没有指定 HTTP header 的地方,但经常我们 POST 的时候是要指定
Content-Type 的,比如说 form submit 通常是 application/x-www-form-urlencoded. 该怎么办呢?浏览器的开发者们不想动这个接口(可以理解,毕竟 NPAPI 已经用了这么多年,大量的 plugin 都用了这个接口,再改会有很多麻烦),就提出了一个很山寨的办法:

你不是有个 buf 吗,以前是用来传输 http body 的,现在你在这个 buf 的头上加上 http header 不就行了吗?


在 https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/URLs 上,Mozilla 还给了一个例子:


char* myData = "Content Type:/tapplication/x-www-form-urlencoded/nContent-Length:/t25/n/nname1=value1&name2=value2/n"; uint32 myLength = strlen(myData) + 1; err = NPN_PostURL(instance, "http://hoohoo.ncsa.uiuc.edu/cgi-bin/post-query","_blank", myLength, myData, FALSE);

结果昨天我在 Firefox 里试了一晚上,一直都不好使。什么原因呢?跟到 Firefox 的源码里面,终于明白了。大家知道 HTTP 协议里面,HTTP header 和 body 之前是有连续两个 /r/n 的。所以上面例子里的 post 会变成:

<前面的header>
(/r/n)
(/r/n)
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
(/r/n)
(/r/n)
<这里是想发的body>

Web 服务器收到这样的请求,在第一对 /r/n/r/n 的时候就会把后面的内容全部当成是 body,所以那个希望加上去的 header 完全不会起作用。

Google了半天,发现不少人在讨论这个问题,但都没说到点子上,还有人说是因为要把 /r/n 换成 /n 的。总之在 Firefox 里是没有办法了,workaround 就是自己重新实现一遍吧。

p.s. 顺便看了一下 WebKit 这部分的代码,倒是正确地按照接口的要求实现了。WebKit 会事先检查 buf 里面有没有 header,有的话加到 header 里。看来 WebKit 倒是挺严谨的。

你可能感兴趣的:(浏览器,Google,header,webkit,firefox,mozilla)