tomcat 解析包含中文的cookie 抛警告源码分析

前段时间一个同事在项目那边日志中报了很多警告,内容是如下这样:

警告: java.lang.IllegalArgumentException: Control character: ffce incookie value or attribute. COOKIE: uc1=lltime=1362664120&cookie14=UoLa%2FgYsjAaa2Q%3D%3D&existShop=true&cookie16=VFC%2FuZ9az08KUQ56dCrZDlbNdA%3D%3D&cookie21=UIHiLt3xSifiVqTH8o%2F0Qw%3D%3D&tag=0&cookie15=WqG3DMC9VAQiUQ%3D%3D;unb=1599477041; _nk_=%5Cu6211%5Cu4EEC%5Cu662F%5Cu5C0Fm; _l_g_=Ug%3D%3D; v=0;cookie2=94e97f84990927f9a94f481a9163b2d5; sg=m13;lastgetwwmsg=MTM2MjY2NDQ1Nw%3D%3D;cookie1=AHt%2BQDOLk7aCMZ0ZrSrfQP4X8Rzo3dfwwMyH74sDz4Q%3D; cookie17=UoTV5YhjXVmj2g%3D%3D;_tb_token_=5f3e03abe138d; mpp=t%3D1%26m%3D%26h%3D1362672860152%26l%3D1362664473890;l=我们是小m::1362670804377::11;x=e%3D1%26p%3D*%26s%3D0%26c%3D1%26f%3D0%26g%3D0%26t%3D0; tg=5;_cc_=V32FPkk%2Fhw%3D%3D; t=82e

0358dd008e1bc374d96050e25dcf5;tracknick=%5Cu6211%5Cu4EEC%5Cu662F%5Cu5C0Fm;uc2=wuf=http%3A%2F%2Fm0.mail.sina.com.cn%2Fclassic%2Findex.php;mt=cp=0&ci=0_0; cna=0EG/CbL/OkwCAW6ncHu5A+dL;CNZZDATA30070035=cnzz_eid%3D35484131-1351603898-http%3A%2F%2Fwww.taobao.com%2F%3Fspm%3Da1z02.1.0.23.Y0l4Gu%26ntime%3D1362664616%26cnzz_a%3D4%26retime%3D1362668703518%26sin%3D%26ltime%3D1362668703518%26rtime%3D3;showPopup=3

2013-3-80:22:27 org.apache.tomcat.util.http.Cookies processCookies

       通过警告的内容可以看出这个是由于cookie中有中文导致的。同事那边判断为子账号登录中文并未转码所致。由于这段时间正在看tomcat的源码,那就来分析一下cookie有中文为什么会抛出这个异常吧!           

1.     首先找个有cookie的域名,我把www.renren.com绑定到127.0.0.1

2.     启动tomcat,找到CoyoteAdapter这个请求处理的适配器类,在解析cookie的部分打断点,CoyoteAdapter类postParseRequest这个方法:


3.     在浏览器中拦截www.renren.com这个请求,将cookie中的一个value改为汉字:


这里我敲了一个“我”字。

4.     进入eclipse调试定位到这行代码跑了异常:



打印在控制台的信息是:

警告: java.lang.IllegalArgumentException: Control character: ffe6 in cookie value orattribute. COOKIE: anonymid=鎴?6ly3rd-ep9utw; _r01_=1;_de=BABDC25FBCDA16FDDDEB086511A3F25034DF20B0B3AA6FF7

          可见与上面服务器日志抛出来的异常是同一个。在来看抛异常的这段代码:

              public static final boolean isV0Separator(final char c) {

        if (c < 0x20 || c >= 0x7f) {

            if (c != 0x09) {

                throw newIllegalArgumentException("Control character: " + Integer.toHexString((c & 0xffff))

                        + " in cookie value or attribute.");

            }

        }

 

        return V0_SEPARATOR_FLAGS[c];

    }

       这个判断的意思是,如果字符的ascii 小于16进制的20和大于等于16进制的7f,并且不等于16进制的9就会抛出这个异常。翻译一下为:如果这个字符的ascii代码不在 [32,127)并且ascii代码不等于9(对应ascii的制表符)就会抛出这个异常。

       异常的代码路径是Cookies类的processCookies方法的第139行:


      

5.     为什么tomcat为什么会有这个规定呢?

查了一下http规范在RFC2965文档上有这么一段:


 网上查了一段cookie的规范也提到:


由此可见tomcat这么限制是遵循http规范的,至于为什么没有把所有的ascii全部涵盖进来,这个还没有仔细研究,有知道的可以分享一下。

6.     所以上面那个服务器的异常解决方案应该就是讲cookie中的中文编码了,毕竟最好不要违反http规范。

              

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值