前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次 .NET Framework 不兼容 HTTP COOKIE 协议标准的问题跟踪

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

原创
作者头像
Austin
发布2018-06-19 17:34:13
8950
发布2018-06-19 17:34:13
举报
文章被收录于专栏:UDNZUDNZ

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

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

代码语言:c#
复制
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 协议,也是允许如下形式的字符串的,看起来也没有什么问题:

代码语言:text
复制
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 头参数:

代码语言:text
复制
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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档