如何使用charlesproxy检查websocket流量以用于iOS模拟器/设备

时间:2015-10-12 20:57:22

标签: ios sockets websocket charles-proxy cfnetwork

我想检查通过网络套接字的网络流量,我无法控制网络代码,因为这是一个我没有源代码的二进制库,所以我不能在代码的网络部分做任何日志/断点

我尝试使用最新版本的 CharlesProxy 声称可以嗅探网页框但是当我尝试使用网址时使用网址时的网址甚至在我的iPhone调用的端点列表中都没有提到

Version 3.11 release notes

我已经验证CharlesProxy配置正确,因为即使在SSL下我也可以检查非websocket流量。

所以我的问题是:有没有人找到一个解决方案来检查通过CharlesProxy通过websockets的流量?

注意:使用iOS9时,我禁用了ATS

谢谢!

4 个答案:

答案 0 :(得分:20)

我终于找到了答案。

Charles 3.11.2与WebSocket完美配合。

我使用socketIO,因此我已经看到在协商阶段发送的http请求,但是我错过了websockets流量。

最初,socketIO尝试使用轮询,然后切换到使用 websockets

当您转到状态为“发送请求正文”的请求时,可以看到websocket流量,这实际上是 wss:// 请求。

您甚至可以为此类流量设置专用标签。其余的消息将出现在那里。

enter image description here

PS1。确保您已正确连接到插座然后它出现在Charles中 PS2。我建议使用socketIO,这对于像websockets这样的全双工流量来说是一个很好的增强。

答案 1 :(得分:2)

可接受的答案似乎不适用于iOS设备上的Socket.IO。

最新版本的Socket.IO-Client-Swift(在撰写本文时为15.0.0)将Starscream用于iOS / OS X上的WebSockets。

好消息是Starscream支持SOCKS代理:

  1. Socket.IO不会公开Starscream Websocket或提供任何用于启用SOCKS代理行为的API。

  2. Starscream内置的SOCKS代理使用OS SOCKS代理设置,这些设置很麻烦(至少对于iOS而言)。

如果我有时间,我可能会提出PR来更彻底地解决此问题,但是鉴于Starscream和Socket.IO-Client-Swift都需要工作,因此这并不完全简单。

为了临时调试目的(这是Charles的用例),解决此问题的最简单方法是编辑WebSocket.swift文件作为Starscream的一部分,并替换以下代码:

if enableSOCKSProxy {
    let proxyDict = CFNetworkCopySystemProxySettings()
    let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue())
    let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
    CFWriteStreamSetProperty(outputStream, propertyKey, socksConfig)
    CFReadStreamSetProperty(inputStream, propertyKey, socksConfig)
}

使用以下代码:

let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, CFNetworkCopySystemProxySettings()!.takeRetainedValue()) as! [String: Any]
let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
let ip = socksConfig["HTTPSProxy"]
let proxySocksConfig = ["SOCKSProxy": ip, "SOCKSPort": 8889, "SOCKSEnable": true] as CFDictionary // Where 8889 is the SOCKS proxy port in Charles
CFWriteStreamSetProperty(outputStream, propertyKey, proxySocksConfig)
CFReadStreamSetProperty(inputStream, propertyKey, proxySocksConfig)

这将确保默认情况下启用SOCKS代理,并将通过Charles路由所有WebSocket流量。

然后,您需要确保在iOS中配置了HTTP代理设置(因为HTTP和SOCKS都将使用相同的IP),在Charles中启用了SOCKS代理,并且端口与上面代码中的端口匹配(默认为8889)。

答案 2 :(得分:0)

感谢您的非常有益的回答Jonathan Ellis! 我正在使用Pusher,效果很好!

但是,我发现socksConfig并不总是包含有效数据,并且当我从那里获取IP时无法正常工作或会使应用程序崩溃。由于我们唯一获得的是本地主机IP,因此我在WebSocket.swift

中替换了以下内容
if enableSOCKSProxy {
    let proxyDict = CFNetworkCopySystemProxySettings()
    let socksConfig = CFDictionaryCreateMutableCopy(nil, 0, proxyDict!.takeRetainedValue())
    let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
    CFWriteStreamSetProperty(outputStream, propertyKey, socksConfig)
    CFReadStreamSetProperty(inputStream, propertyKey, socksConfig)
}

与此:

let propertyKey = CFStreamPropertyKey(rawValue: kCFStreamPropertySOCKSProxy)
let proxySocksConfig = ["SOCKSProxy": "127.0.0.1", "SOCKSPort": 8889, "SOCKSEnable": true] as CFDictionary // Where 8889 is the SOCKS proxy port in Charles
CFWriteStreamSetProperty(outputStream, propertyKey, proxySocksConfig)
CFReadStreamSetProperty(inputStream, propertyKey, proxySocksConfig)

然后按照您所描述的在Charles中启用袜子代理。

再次感谢!

答案 3 :(得分:0)

找到了一种解决方法: 尝试之后,我得出结论,尽管iOS模拟器遵循 HTTP 的系统代理设置,但未遵循 WebSocket 。也没有遵循Socks5代理设置。 但是,我们可以在Charles中使用Reverse Proxies来强制模拟器使用它。 在Charles中,单击Proxy -> Reverse Proxies,设置一个本地地址作为您的WebSocket服务器的透明代理,然后在您的new WebSocket(<address>)中使用该地址(对于React Native来说是这样),然后您可以看到您的WebSocket联系出现在查尔斯