链接内容保存成文件的命名规范和IE保存moinmoin附件中文文件名乱码的解决

Posted on Tue 25 May 2010 in 我用(IT)

昨天群峰找我商量解决一个问题,问题的现象是这样的:有一个提供软件包下载的服务,用浏览器下载软件包,另存为的文件名是正确的;但用手机客户端下载,存成的文件名就是下载链接的一长串地址信息且内容为空;用wget模拟更古怪,在一台机器上能存成正确的,另外一台就是地址信息。我又帮他测试了一下,用E52 可以正确下载并保存文件名,wget在xp和ubuntu下头保存的都是链接地址。

可惜当年做这个系统和测试这个功能的人都已经不在了,据说当时竟然测试通过了,难道也是用E52测试的?

群峰用wget -d把Http头信息打出来,内容如下:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Connection: Keep-Alive
Content-Disposition: attachment; filename="NetQin_P0_AV_S60OS70v2_4_28.SIS"
Accept-Ranges: bytes
Content-Type: application/vnd.symbian.install
Content-Length: 476517
Date: Tue, 25 May 2010 02:45:33 GMT
Connection: keep-alive


文件名是写在Content-Disposition里了,google了一下,原来是RFC 1806: Communicating Presentation Information in Internet Messages: The Content-Disposition Header定义的规范。看来有些客户端浏览器和wget都不支持啊。

于是提出一个改进方案,服务器接到请求链接后302跳转到下面这个链接,任何支持保存的客户端应该都能正确工作了:/download/id/NetQin_P0_AV_S60OS70v2_4_28.SIS

不过还是有点儿不死心,在上面这份文档里面还提到了RFC1341:大概意思是这样的,RFC1341在HTTP头的Content-Type中定义了一个NAME字段用来建议打算写成文件的名称,但随后产生的 RFC 1806在HTTP头中独立出一个Content-Disposition来定义文件名,并且废弃了RFC1341中的那个约定。

可以再尝试一下用RFC1341的约定吧,写法大致是这样的:

Content-Type:  application/octet-stream;
                      name=foo.tar.Z; type=tar;
                      conversions="x-encrypt,x-compress"

在分析这个问题是忽然想到了解决IE保存moinmoin中文附件的乱码问题的办法:

# AttachFile.py line 820
        # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs
        # There is no solution that is compatible to IE except stripping non-ascii chars
        # add by LiYan@20100525 fix chinese file name failed to save
        ua = request.http_user_agent
        if ua.find("MSIE")!=-1:
            filename_enc = filename.encode("GBK")
        else:
            filename_enc = filename.encode(config.charset)

就是适配一下儿是不是IE浏览器,如果是的话用GBK编码。测试通过,呵呵,两年前没有头绪的事情啊,就这么搞定了。