工作时使用了Websocket技术,在使用的过程中发现,浏览器(Chrome)升级后可能会导致Websocket不可用,更换浏览器后可以正常使用。

近日偶尔一次在本地调试,发现使用相同版本的Chrome浏览器,不可连接线上服务器的WS服务,但是可以连接本地的WS服务。 此时初步怀疑是服务器在某种特殊情况下会触发无法连接的问题。

使用Wireshark抓包

Filter:    ip.dst==serverIP or (ip.dst==本地IP and ip.src==serverIP)

一.查看可以正常连接线上服务的浏览器的网络请求(搜狗高速核)

可以看到WebSocket连接建立的步骤:

1、先建立TCP连接,1~3条为tcp连接的三次握手

2、发出一个http请求,Header内容如下

GET /write?agentId=255 HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 10.134.71.235:2015
Origin: http://10.134.71.235
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: NddL4PEqgeUKIon0p+IHwQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0
Cookie: ASP.NET_SessionId=kdparak1ecjplo4erozul2yl; _un=zouchengzhuo@sogou-inc.com; id=77.NRe6bXSRddXY6INl1HMkRAdn7L4yIt4wcTGYu43q9r4; un=zouchengzhuo@sogou-inc.com; pw=70467311a7ed8f62b58f8f1d65cdb408

websocket连接http请求header内容

服务器返回

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: LDedYtTLpS6J7EygF4awEchi+D4=

websocket连接http请求返回

3.连接建立成功,使用WebSocket协议收发消息

其中[FIN][MASKED] 为浏览器给server发消息

[FIN]为server给浏览器发消息,浏览器收到后发一个TCP的 [ACK] 包确认

正常的网络请求知道了,接下来服务器不变,更换浏览器

二、查看无法正常连接线上服务器的网络请求(Chrome)

可以看到,HTTP请求发出去后,没有收到101的回复,服务器直接发起了TCP连接断开的流程。

怀疑是HTTP请求的内容不对。查看请求header

GET /write?agentId=255 HTTP/1.1
Host: 10.134.71.235:2015
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://10.134.71.235
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: ASP.NET_SessionId=1rfwnghibfq2jvvjrlbflvl0; _un=zouchengzhuo@sogou-inc.com; id=77.NRe6bXSRddXY6INl1HMkRAdn7L4yIt4wcTGYu43q9r4; un=zouchengzhuo@sogou-inc.com; pw=IsQky+6I5U5zM89pna9UNNirBD9v74G5799FdJvrK78aLTw0mvq5icQJpNlCweeHTl646j88InE03ayWm4PpcA==
Sec-WebSocket-Key: kcEwLRS2BowYzsoYxGCQNw==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

和搜狗的包对比,好像没有任何问题,接下来浏览器不变,更换服务器

三、查看可以正常连接的本地服务器的网络请求(Chrome)

连接建立过程正常,就不用截图了,主要关注HTTP请求header里边的内容

GET /write?agentId=255 HTTP/1.1
Host: 10.129.157.168:2015
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin:http://localhost:8317
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Sec-WebSocket-Key: ldwAY7BvJ6c0Gt9Xbh/R/Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

分析原因

分析发现,这个header里边没有cookie的数据,推测有可能是http请求里边的cookie导致连接断开。

chrome

这里就发现了第一个奇怪的问题,Chrome为什么有的时候会发送cookie,有的时候不会呢?

经过多次调试发现:

1.关闭浏览器并重启的第一次,使用m.venus.sogou-inc.com访问,是可以正常使用的

2.无论何时,通过IP直接访问服务器都无法连接

3.只要用IP访问过,用域名访问也无法正常连接了

分析Cookie

用域名访问时的Cookie

用IP访问时的Cookie

公司对m.venus.sogou-inc.com的解析是经过了代理服务器的,目前OP的nginx还不能转发ws协议的请求

所以浏览器创建Websocket的方式 是  new WebSocket('ws://ip:port') 而不是 new WebSocket('ws://hostname:port')

重启浏览器,用域名访问的时候,header中

Host: 10.134.71.235:2015
Origin: http://m.venus.sogou-inc.com

这是一个跨域的http请求,所以请求中默认是不会带上cookie的,chrome对在ws协议中的http请求中,显然也是应用的这个默认设置。

用IP访问的时候

Host: 10.134.71.235:2015
Origin: http://10.134.71.235

这是一个同域的请求,所以会带上cookie。 第二个问题得到了解释

一旦用ip访问过,在此ip下就种下cookie了,而即使是在域名访问的情况下,ws协议发出的http请求的host也是ip:port,所以也会发送ip下的cookie。

可以看到cookies的生命周期都是session级别的,所以重启浏览器后再用域名访问是可以的

第一、三个问题得到了解释

但是,搜狗浏览器的请求里边也包含了Cookie,为何搜狗却可以正常连接服务器呢?

搜狗高速核

用搜狗高速核多次试验,发现:

1.搜狗高速核的cookie数据中没有发送sessionid

2.搜狗浏览器不管任何时候,都会发送cookie

用域名访问的cookie:

用IP访问的cookie:

通过对比cookie的值发现,发送的cookie是ip域下的cookie。

那么这里有两个没办法解释的问题

1.为什么带有httponly属性的cookie,搜狗浏览器在发送请求的时候不会发出去

2.为何关掉所有搜狗浏览器的进程后,生命周期为session的cookie没有被干掉

这是不是搜狗浏览器的两个BUG呢?

到此时基本可以确定,就是因为cookie中带了sessionid导致服务器主动断开连接。

云平台的Websocket服务器是用Alchemy Websockets开发的。按照正常的逻辑,WebSocket服务器中不应该用session去判断用户身份,因为它和Http不属于同一个会话。

现在怀疑是因为Alchemy WebSockets组件的BUG导致此问题。

调试Alchemy WebSockets源码

首先在本地IIS中发布一个云平台服务器,然后在VS中开启一个调试的服务,通过IP登录一下本地的云平台,然后通过localhost:调试端口 访问调试的服务,以模拟ws连接的http请求中带上cookie的情况。

从连接开始阶段打上断点单步调试,到Handshake.cs类的时候发现一个方法:

        public bool IsValid()
{
return (
(Host != null) &&
(Key != null) &&
(Int32.Parse(Version) >= )
);
}

在正常情况下此方法返回true,请求中带上cookie且含有sessionId后返回false。原因是key==null。

抓包得到的header:

GET /write?agentId=261 HTTP/1.1
Host: 10.129.157.168:2015
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:8317
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: ASP.NET_SessionId=5qmgzihkxtvntxirmekbm2tv; _un=zouchengzhuo@sogou-inc.com; id=77.NRe6bXSRddXY6INl1HMkRAdn7L4yIt4wcTGYu43q9r4; un=zouchengzhuo@sogou-inc.com; pw=RGPCwqEawjg9JXHVZ/rLzM4Ac1+nDHlL2y1kKYp6PVLkZ5o/Oj5/OsP8t8vsg3D+djE3x0Q7zH/7ggw2Jme63A==
Sec-WebSocket-Key: TLjHvbrhmKqEK3sNPu7bnA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_windo

可以看到Sec-Websocket-Key 是存在的。

调试进入分析处理header的类里边,发现收到的header字符串为

GET /write?agentId=261 HTTP/1.1
Host: 10.129.157.168:2015
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:8317
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: ASP.NET_SessionId=5qmgzihkxtvntxirmekbm2tv; _un=zouchengzhuo@sogou-inc.com; id=77.NRe6bXSRddXY6INl1HMkRAdn7L4yIt4wcTGYu43q9r4; un=

发现header少了一段。继续分析这个组件的代码,发现

Handler.cs 中:

TCPServer中:

默认只读取了512字节的数据,把这里改为一个足够大的大小来测试一下,就没问题了。

至此问题的原因找到了,Alchemy WebSockets在处理ws连接第二步——发送http请求的时候,对http头的解析方法有问题,导致丢掉了关键性的数据,浏览器中生成的 Ses-Websocket-Key,以至于服务器认为这是个非法的连接请求,给干掉了。

将处理header的地方修改为读取所有数据再处理,就能解决这个问题。

但是调试过程中还是留下了两个疑问:

1.为什么带有httponly属性的cookie,搜狗浏览器在发送请求的时候不会发出去

2.为何关掉所有搜狗浏览器的进程后,生命周期为session的cookie没有被干掉

使用wireshark抓包分析浏览器无法建立WebSocket连接的问题(server为Alchemy WebSockets组件)的更多相关文章

  1. Wireshark抓包分析TCP建立/释放链接的过程以及状态变迁分析

    Wireshark抓包分析TCP建立/释放链接的过程以及状态变迁分析 一.介绍计算机网络体系结构 1.计算机的网络体系结构 在抓包分析TCP建立链接之前首先了解下计算机的网络通信的模型,我相信学习过计 ...

  2. wireshark 抓包分析 TCPIP协议的握手

    wireshark 抓包分析 TCPIP协议的握手 原网址:http://www.cnblogs.com/TankXiao/archive/2012/10/10/2711777.html 之前写过一篇 ...

  3. FTP协议的粗浅学习--利用wireshark抓包分析相关tcp连接

    一.为什么写这个 昨天遇到个ftp相关的问题,关于ftp匿名访问的.花费了大量的脑细胞后,终于搞定了服务端的配置,现在客户端可以像下图一样,直接在浏览器输入url,即可直接访问. 期间不会弹出输入用户 ...

  4. wireshark抓包分析——TCP/IP协议

    本文来自网易云社区 当我们需要跟踪网络有关的信息时,经常会说"抓包".这里抓包究竟是什么?抓到的包又能分析出什么?在本文中以TCP/IP协议为例,简单介绍TCP/IP协议以及如何通 ...

  5. http2 技术整理 nginx 搭建 http2 wireshark 抓包分析 server push 服务端推送

    使用 nginx 搭建一个 http2 的站点,准备所需: 1,域名 .com .net 均可(国内域名需要 icp 备案) 2,云主机一个,可以自由的安装配置软件的服务器 3,https 证书 ht ...

  6. Wireshark抓包分析/TCP/Http/Https及代理IP的识别

    前言 坦白讲,没想好怎样的开头.辗转三年过去了.一切已经变化了许多,一切似乎从没有改变. 前段时间调研了一次代理相关的知识,简单整理一下分享之.如有错误,欢迎指正. 涉及 Proxy IP应用 原理/ ...

  7. Wireshark抓包分析HTTPS与HTTP报文的差异

    一.什么是HTTPS: HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议 它是一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务器之间交换 ...

  8. 使用wireshark抓包分析-抓包实用技巧

    目录 使用wireshark抓包分析-抓包实用技巧 前言 自定义捕获条件 输入配置 输出配置 命令行抓包 抓取多个接口 抓包分析 批量分析 合并包 结论 参考文献 使用wireshark抓包分析-抓包 ...

  9. WireShark抓包分析以及对TCP/IP三次握手与四次挥手的分析

    WireShark抓包分析TCP/IP三次握手与四次挥手 Wireshark介绍: Wireshark(前称Ethereal)是一个网络封包分析软件.功能十分强大,是一个可以在多个操作系统平台上的开源 ...

随机推荐

  1. SecurityContextHolder.getContext().getAuthentication() return null

    <security:http> <security:intercept-url pattern="/web/**" access="IS_AUTHENT ...

  2. (转)名称和本质 by王珢

    名称和本质 by 王垠 我很喜欢 Richard Feynman 写的 <What Do You Care What Other People Think>.在最开头 Feynman 讲到 ...

  3. 代码-->发呆

    代码,敲着敲着,就发呆了. 其实安安静静敲代码,是一种享受.开着不快不慢的音乐,徜徉在代码的世界里,忘记了时间的存在. 原本备忘录中提醒我13点看书,一小时又一小时的延后,已经不记得自己按了多少次一小 ...

  4. Smart3D系列教程2之 《为什么三维重建效果这么差?——探探那些被忽略的拍照要求和技巧》

    一.照片采集的实用概念 根据照片进行三维重建的过程中,有人没怎么遇到坑,有人被坑的不轻.可能是模型的纹理失真,模型的法线错了,模型会生成我们各种也想不到的结果,那么,是什么导致三维重建效果这么差的?是 ...

  5. Javascript初学篇章_6(BOM)

    BOM 浏览器对象模型 BOM (浏览器对象模型),它提供了与浏览器窗口进行交互的对象 一.window对象 Window对 象表示整个浏览器窗口. 1.系统消息框 alert() alert('he ...

  6. <2048>调查报告心得与体会

    老师这次给我们布置了一个任务,就是让我们写一份属于自己的调查报告,针对这个任务,我们小组的六个人通过积极的讨论,提出了一些关于我们产品的问题,当然这些问题并不是很全面,因为我们是从自己的角度出发,无法 ...

  7. FFT时域与频域的关系,以及采样速率与采样点的影响

    首先对于FFT来说,输入的信号是一个按一定采样频率获得的信号序列,而输出是每个采样点对应的频率的幅度(能量). 下面详细分析: 在FFT的输出数据中,第一个值是直流分量的振幅(这样对应周期有无穷的可能 ...

  8. ThoughtWorks代码挑战——FizzBuzzWhizz

    很久没发表过文章了,今天看到一篇文章 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏(C#解法) 看到LZ的2B青年代码,实在是惨不忍睹,故写篇文章来探讨下这类 ...

  9. 不知道张(zhāng)雱(pāng)是谁?你out了!

    张(zhāng)雱(pāng)是谁?也许你已经听说过了,也许你还没听说过呢,不过你一定听说过老刘——刘强东,没错,这二人是有关系的,什么关系,京东是老刘的,而张雱呢?张雱是京东旗下52家关联公司法人代 ...

  10. 【Prince2是什么】PRINCE2认证之Prince2衡量绩效的六大要素

      之前一篇文章已经跟大家从体系上讲解了PRINCE2和PMP的差异,那接下来我们进行第二讲,PRINCE2中讲到的衡量绩效的要素是什么呢? 第一,成本:即项目必须是所能负担的起的 第二,时间:即项目 ...