记一次 .NET Framework 不兼容 HTTP COOKIE 协议标准的问题跟踪

我们在后端系统实现了 HTTP 请求的代理类,用于请求其他第三方系统。大致的请求流程是这样的:

消费系统不能直接请求业务系统的 HTTP 接口,需要由中间的 HttpHelper 代理请求。其中 HttpHelper 接受消费系统传入的各种参数,包括要请求的 URL、METHOD、HEAD、BODY 等,在实际生产中一直运行得很好,直到如下异常的出现:

System.Net.CookieException: Cookie format error.
at System.Net.CookieContainer.CookieCutter(Uri uri, String headerName, String setCookieHeader, Boolean isThrow)

跟进异常信息,很容易知道是设置 Cookie 时发生的异常。根据请求端传入的 HEAD 信息排查,我们很容易还原故障现场:传入 HTTP 头信息 Cookie: expires=Fri, 15 Jun 2018 15:19:14 GMT

这里是在设置 Cookie 的过期时间,并且这个时间看起来也正常,并没有格式错误或者时间不存在的错误。看起来问题不出在时间本身上。上网查查 HTTP 规范,根据 HTTP Cookie 协议,也是允许如下形式的字符串的,看起来也没有什么问题:

Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT

既然异常是微软代码抛出来的,也给了具体抛出异常的方法的地方,那么我们就来翻翻微软代码吧。终于,在微软代码 System.Net.Cookie.VerifySetDefaults:L382 发现了问题所在。在这里,微软在校验 Cookie 值时,如果发现指定的值字符串中有保留字符(“,”、";"),则要求该值必须使用双引号引起来,否则就会抛出异常。查看我们请求的头,在 expires 的值“Fri, 15 Jun 2018 15:19:14 GMT”中,的确有“,”存在,并且值也并未使用双引号引起来。于是我尝试修改传入的 HTTP 头参数:

Cookie: expires=“Fri, 15 Jun 2018 15:19:14 GMT”

很自然,异常不再存在了,目前看起来的确是微软的这段代码导致了抛出异常。

你们我们来看看,这个值到底是不是可以去加双引号吧。继续上网翻文档,在 rfc2965#section-3.1 和 rfc6265#section-4.1.1 中提到,值可以是字符串或引号引起来的字符串(quoted-string),这是 在 HTTP State Management Mechanism 中有所规定的。那么我们可以很放心地做这个兼容性处理了,即,当传入的 Cookie 值包含保留字符,并且未被双引号引起来时(一定会产生异常),我们自动地追加双引号,把值引起来,这样既可避免微软对值进行严格校验时抛出异常了。

但是,此事还没有到此为止,我们实际来试试,加了双引号之后,业务系统是否能够正确收到消费系统传入的头呢?收到的头,是否为消费系统的正确意图呢?

值得注意的是,在业务系统里获取到的 Cookie 值,是添加了引号的值,并不是严格地与消费系统里传入的文本一致。

到此为止,应对这个异常便有两个方案了:

  1. 传入的 Cookie 值包含保留字符,并且未被双引号引起来时(一定会产生异常),我们自动地追加双引号。
  2. 什么都不做,按原意抛出异常,提醒调用者更正 HTTP 头信息的格式。

在我们的项目中,由于情况特殊(使用场景为后端服务之间的通信交互),一般不涉及到 Cookie 的设置,并且消费服务可能由很多个不同的团队实现,而业务服务可以统一处理添加的双引号,因此我们采用了方案 1。至于其他场景,实际上个人偏向于采用方案 2,不掩盖任何问题——特别是因为加了双引号之后,请求接受端接收到的值,不能完全原样表达请求发起端设置的值。

参考:

[1] https://en.wikipedia.org/wiki/HTTP_cookie [2] https://referencesource.microsoft.com/#System/net/System/Net/cookie.cs,67f8e4d3cb862668 [3] https://referencesource.microsoft.com/#System/net/System/Net/cookie.cs,dca3e494aed8e006 [4] https://tools.ietf.org/html/rfc6265#section-4.1.1 [5] https://tools.ietf.org/html/rfc2965#section-3.1 [6] https://tools.ietf.org/html/rfc2616

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 zhuanlan_guanli@qq.com 删除。

发表于

扫描关注云+社区

UDNZ

3 篇文章10 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

扫描关注云+社区