标签:
从规格说明上看,WebSocket毋庸置疑是可以通过HTTP Proxy Server代理访问出去的,不论是非加密的ws://,还是加密的wss://,都应该可以。当然有个通常都满足的前提:HTTP Proxy Server提供socket连接级别的无过滤转接,是所谓的CONNECT命令(而不光是HTTP整体请求响应的转接和过滤)。现实因为如果不提供这个CONNECT命令支持,那么HTTPS网站就用不了(原因一句话说不清,当然通过伪造SSL证书等手段也是可以的,只是需要browser机器这边配合)。总之,HTTP Proxy Server从原理上看,一旦支持了CONNECT命令,那么他后来就对连接中发生的加密内容基本上就是干瞪眼,无法区分到底是不是HTTPS了,从某种意义来说,这是HTTP Proxy Server设计上的一种漏洞。
事实上的确我使用WebSocket一段时间,和http proxy配合也正常,wss(加密)和ws(不加密)两种协议都行,
可有一天在一个http proxy环境下发生问题了!
经过一番疑神疑鬼的调查,最终确定是自动配置script里没有对wss类型提供proxy server ip和port,而只是回答了一个direct (就是不经过proxy server直接连接),所以失败了。
对策很简单,修改pac或者配置一个固定的proxy的ip,port。
memo一下调查经过:
所用工具:socat
在Firefox/Chrome/IE里,使用加密型WebSocket: new WebSocket(‘wss://x.y.z/test‘),爆出错误说timeout, 而非加密型 new WebSocket(‘ws://x.y.z/test‘) 也报错。
Proxy 配置:
自动: http://proxyserver/config.pac
调查开始:
先搞清楚这个config.pac干什么的,其实是个根据url, host来回答该用什么proxy server的东西,而且是个javascript。例如:
function FindProxyForURL(url, host) {
if (url.substring(0, 5) == "http:") {
return "PROXY proxy:80";
} else if (url.substring(0, 6) == "https:") {
return "PROXY secproxy:8080";
} else {
return "DIRECT";
}
}
那看了一下就是用secproxy:8080了啊,https都正常访问了,为啥wss出毛病?
当时绕了个弯子,想要看看http proxy内部发生了什么,于是就拿socat工具来做个中转来分析,这是个神器,以后在写一些活用法。
Run:
socat -v tcp-listen:8080,reuseaddr,fork tcp-connect:secproxy:8080
就是用来做一个假的proxy server,本地的。其中的动作都转接到真的proxy server里去,
然后设定Browser通过这个假的Proxy server访问,于是可以看到其中的来往数据,
内容就省略了。着么折腾了一下也忘了抓取屏幕,忘了是怎么搞的,似乎是server对Websocket的握手请求作出回答后,browser就没有继续请求了,反正意识到自签名的证书会导致问题:WebSocket Server那边的server ssl证书是自签名的,那么可能这边不承认,嗯,的确有人说是,那好,我把证书给作为[可信赖的顶级证书发型者]来加入到系统,哦,https访问网站时的叉号消失了。
着么搞一下,的确wss可以了。
但是回到真环境,发现还是不行,最后用Sysinternal‘s Process Monitor工具追踪网络调用,发现browser居然不通过proxy就直接出去,于是出错了。
去掉自动配置选项,改成固定的proxy的ip,port就好了。
最终,我觉得websocket在选择Proxy server的方法上做的有点傻?居然直接傻乎乎问wss://somesite 该用什么proxy server,而不是聪明的问https://somesite该用什么网站。
转自自己的 http://osexp2003.blogspot.jp/
WebSocket在HTTP Proxy下是可以,可是有点小笨拙之处给人造成不便
标签:
原文地址:http://my.oschina.net/u/2253129/blog/420488