这两天碰到一个问题,一些手机浏览某些图片无法显示,而pc,其他手机上都能正常显示;lighttpd确实收到了这些手机的下载请求,但是返回了400 Bad request错误,错误日志也没有记录什么异常。

上网搜了半天,搜“lighttpd wap”没有任何结果,只好换成“lighttpd mobile”,这下看到一个nokia的字样,兴奋,打开果然和我们碰到的问题一样:http://redmine.lighttpd.net/issues/1351.

诺基亚手机某些型号(6680)在浏览wap页面时,发送的header如下: Accept: text/html, application/vnd.wap.xhtml+xml, application/xhtml+xml, text/css, multipart/mixed, text/vnd.wap.wml, application/vnd.wap.wmlc, application/vnd.wap.wmlscriptc, application/java-archive, application/java, application/x-java-archive, text/vnd.sun.j2me.app-descriptor, application/vnd.met.ticket, application/x-wallet-appl.user-data-provision, application/vnd.oma.drm.message, application/vnd.oma.drm.content, application/vnd.wap.mms-message, application/vnd.wap.sic, text/x-co-desc, application/vnd.oma.dd+xml, application/x-javascript, text/ecmascript, /, text/x-vcard, text/x-vcalendar, image/gif, image/vnd.wap.wbmp Accept-Charset: iso-8859-1, utf-8, iso-10646-ucs-2; q=0.6 Accept-Encoding: gzip,deflate,identity;q=0.9 Accept-Language: zh-cn, zh <font color=red>Content-length: 0</font> Via: WTP/1.1 GDSZ-PS-GW002-WAP03.gd.chinamobile.com (Nokia WAP Gateway 4.1 CD1/ECD13_D/4.1.04) X-Forwarded-For: 10.230.30.174, 211.139.151.10 …… 关注其中Content-length这行,手机浏览器填的值为0,而其他浏览器不发送Content-length; 由于http协议规定get、head等方法不能带body,所以lighttpd就做了一下限制: <pre class=c name=code> case HTTP_METHOD_GET: case HTTP_METHOD_HEAD: /* content-length is forbidden for those / if (con->request.content_length != -1) { / content-length is missing / if (srv->srvconf.log_request_header_on_error) { ERROR(“GET/HEAD with content-length: %d”, 400); }</pre> 所以nokia浏览lighttpd的页面时,会返回400错误。 修正这个问题很简单,改成下面的代码就可以了: <pre class=c name=code> /if (con->request.content_length != -1) {*/ if (con->request.content_length != -1 && con->request.content_length != 0) {</pre> 初步测试通过,firefox/ie6~8/chrome/safari/迅雷等下载都没问题。

另外,很疑惑的是,这个问题1年前就提交到lighttpd的trac中,不知道为什么一直不修改。


Simon Lee

My blog