Apache 有一个问题,中文名字的文件不能Download
系统上线,完成后,测试人员发现页面上的报表不能下载.经了解发现,系统上线前正常,上线的模块也不包括这块功能的改动,只是换了一个数据库,就不能正常下载了,真是蹊跷.
经过开发人员的问题定位,仍然没有能解决问题,于是乎,就又开始了有病乱投医的方法论,每个人说着不着边际的解决办法,同时也没有人去静下心来真正的想想办法,毫无思路,真是一丘之貉.
无奈之下,本来不是自己管辖同时也并不懂这些开发的东西,只能硬着头皮,静下心来,想想看看能不能找到问题的解决方法,只是为了能够早点回家.
问题分析:
1)上线前一切正常
2)未从改动过该模块
3)从内网访问页面,可以直接下载文件
4)从外网不行(外网经过了Apache)
于是就有人去查apache的配置,看是否正确?--无稽之谈
同时经过测试,发现如果下载英文名字的文件,就ok;中文名字的文件失败,那问题就好说了,估计对中文解析不对,编码有问题.
按照这个思路,去google搜了下,发现了如下这篇文章.
于是解决问题,非常之简单,打开IE去掉个小勾就OK了.
又一次感受到了思路的重要性.
--有关apache中文url问题
使用apache+weblogic部署的网站,发现通过weblogic的7001端口下载中文文件名的文件没有问题,但是通过apache下载会出现404错误,经查看是因为apache对中文url的支持有问题。
1.IE访问WEB的简单顺序为:
IE<->apache<->文件系统
即IE向apache发送URL请求,该请求是通过某种编码做了encode的,apache接到请求后对其进行解码,然后再用解码后的地址到文件系统获取请求的内容返回到客户端的IE。
从以上顺序可以看出,如果要正常使用中文路径的URL,必须保证:1,IE端到apache端的URL请求的编码和解码的字符集必须一致,2,apache到文件系统获取中文路径内容使用的字符集也要跟文件系统的文件名的编码一致。
2.ext2、ext3等文件系统(ufs文件系统估计也是)不像ntfs或者fat32文件系统,前者文件名是用原码的,不作任何编码,而后者是通过Unicode编码的,故而在win机器上的apache到文件系统获取中文路径的文件的问题不大,但是在Linux/Unix上,就必须保证使用正确的字符编码才能正确访问中文路径了。
3.IE默认是通过UTF8发送URL请求的,如果不想用UTF-8,即必须修改IE的配置,具体方法是IE选项->高级->不选总是以UTF-8发送URL。
4.ftp协议一般都是通过GBK编码作为路径编码传输文件的,故而要正确访问ext2、ext3经过ftp传输的中文路径文件,必须使用GBK才能正确访问到,我用zh_CN.GB18030编码可以成功访问。
根据以上等出结论,对Weblogic和Apache做了测试结果如下:
weblogic在Linux/Solaris上:
1.将启动weblogic进程的用户的编码设置为zh_CN.GB18030,这样可以保证weblogic服务器正确访问文件系统的中文路径的文件,我测试了其它字符集,即不能正常访问到;
2.weblogic,默认指定请求解码字符集为Encoding="UTF-8"(config.xml中定义),那么,IE如果用UTF-8发送URL请求的话是可以正确访问到中文路径的内容的;
3. 修改weblogic配置,指定请求解码字符集Encoding="GBK",那么,IE如果用UTF-8发送URL请求的话将不能正确访问到中文路径的内容,可以将IE设置为“不总是以UTF-8发送URL请求”,即此时可以正确访问。
注意:如果请求的是jsp等java内容,还必须对程序做修改,使其使用正确的编码和解码字符集做get和put操作,才能正常,这个由开发人员完成测试。
Apache在Linux/Solaris上:
1.尚未找到Apache修改请求解码字符集设置的地方,或者根本apache本来就没得修改,已经写死在apache程序里面,除非修改程序才能修改指定URL请求的解码字符集,在这种情况下,将IE设置成了“不总是以UTF-8发送URL请求”,那么也是可以正确访问中文路径的内容的。
综上所述,如同只是单独使用weblogic,那么可以根据实际情况选择某种方式;如果使用Apache或者apache结合weblogic,那么只能迁就Apache,故而必须要求客户端将IE修改成了“不总是以UTF-8发送URL请求”才能正常使用中文路径URL。由于IE默认情况下就是配置成用UTF-8发送请求,故而后者比较麻烦!
还有种方法就是加模块,在apache处理url前,把它们处理成通用的utf-8
方法如下
■下载相关文件并解压
WebDAV Resources JP有Apache2对应的mod_encoding的最新版本下载
# wget http://webdav.todo.gr.jp/download/mod_encoding-20021209.tar.gz
# wget http://webdav.todo.gr.jp/download/experimental/mod_encoding.c.apache2.20040616
# tar zxfv mod_encoding-20021209.tar.gz
# cp mod_encoding.c.apache2.20020616 mod_encoding-20021209/mod_encoding.c(不进行该步操作,在编译mod_encoding模块时会报下面的错误:apxs:Error: Command failed with rc=65536)
■iconv_hook编译和安装
安装mod_encoding前首先需要安装iconv_hook。
$ cd mod_encoding-20021209/lib
$ ./configure
$ make
# make install
完成上面操作后,iconv_hook相关so文件放到/usr/local/lib下面。
要操作系统系统能够搜索到该so文件,需要完成一下几行操作
打开/etc/ld.so.conf文件,添加一行指向iconv_book的所在路径,即"/usr/local/lib"
# vi /etc/ld.so.conf
/usr/local/lib
# PATH="$PATH:/sbin"
# ldconfig 这一步必须要做
■ mod_encoding模块的编译
进入mod_encoding-20021209.tar.gz的解压目录,即mod_encoding-20021209
# ./configure --with-apxs=/opt/apache/bin/apxs --with-iconv-hook=/usr/local/include
# make
#ls -l mod_encoding.o
查看是否已经生成了mod_encoding.o文件,如果是,则make成功继续下边的操作。
# gcc -shared -o mod_encoding.so mod_encoding.o -Wc,-Wall -L/usr/local/lib -Llib -liconv_hook
生成mod_encoding.so文件,将该文件拷贝到你的模块存放目录,一般为${APACHE_HOME}/modules/
# cp mod_encoding.so /opt/apache/modules/mod_encoding.so
■ httpd.confd的設定
这个是我的设置文件,参考的ytang的
LoadModule headers_module modules/mod_headers.so
LoadModule encoding_module modules/mod_encoding.so
<IfModule mod_headers.c>
Header add MS-Author-Via "DAV"
</IfModule>
<IfModule mod_encoding.c>
EncodingEngine on
NormalizeUsername on
SetServerEncoding GBK
DefaultClientEncoding UTF-8 GBK GB2312
AddClientEncoding "(Microsoft .* DAV $)" UTF-8 GBK GB2312
AddClientEncoding "Microsoft .* DAV" UTF-8 GBK GB2312
AddClientEncoding "Microsoft-WebDAV*" UTF-8 GBK GB2312
</IfModule>
另外,mod_encoding需要 mod_headers的支持,如果自己编译apache,别忘了把mod_headers选上。