如何使用 charlesproxy 检查 websocket 流量 iOS simulator/devices
How to inspect websocket traffic with charlesproxy for iOS simulator/devices
我想检查通过 web sockets 的网络流量,我无法控制网络代码,因为这是一个二进制库,我没有源代码,所以 我无法在代码的网络部分执行任何 log/breakpoint。
我已经尝试使用最新版本的 CharlesProxy,它声称能够嗅探 websockets 但是当我尝试 url 并且甚至没有提到使用 websockets 的 api在从我的 iPhone.
调用的端点列表中
我已验证 CharlesProxy 配置正确,因为即使在 SSL 下我也能够检查非 websocket 流量。
所以我的问题是:有没有人找到解决方案来检查使用 CharlesProxy 通过 websockets 的流量?
注意:我在使用 iOS9
时禁用了 ATS
谢谢!
我终于找到了答案。
Charles 3.11.2 与 WebSocket 完美配合。
我使用 socketIO,所以我已经看到在协商阶段发送的 http 请求,但是 我错过了 websockets 流量。
一开始,socketIO尝试使用polling然后切换到使用websockets.
当您转到状态为 "Sending request body" 的请求时,websocket 流量是可见的,实际上是 wss:// 请求。
您甚至可以为此类流量设置专门的标签。其余消息将显示在此处。
PS1。确保您已正确连接到套接字,然后它会出现在 Charles 中。
PS2。我建议使用 socketIO 它是对像 websockets 这样的全双工流量的一个很好的增强。
更新: 显然 socket.io-client-swift v15.1.0 现在可以正确支持 SOCKS 代理。我还没有尝试过,但这意味着不再需要对红蜘蛛进行这些手动编辑。
接受的答案似乎不适用于 iOS 设备上的 Socket.IO。
Socket.IO-Client-Swift 的最新版本(撰写本文时为 15.0.0)在 iOS/OS X 上使用 Starscream 作为 WebSockets。
好消息是红蜘蛛支持 SOCKS 代理:
Socket.IO 不公开 Starscream websocket 或提供任何 API 来启用 SOCKS 代理行为。
红蜘蛛内置的 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 路由所有 websockets 流量。
然后您需要确保在 iOS 中配置了 HTTP 代理设置(因为 HTTP 和 SOCKS 将使用相同的 IP),在 Charles 中启用了 SOCKS 代理,并且端口匹配上面代码中的端口(默认 8889)。
感谢乔纳森·埃利斯的非常有用的回答!
我正在使用 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 中启用了 socks 代理。
再次感谢!
找到解决方法:
尝试后,我得出结论,尽管 iOS 模拟器遵循 HTTP 的系统代理设置,但未遵循 WebSocket。也不遵循 Socks5 代理设置。
但是,我们可以在Charles中使用Reverse Proxies
来强制模拟器使用它。
在Charles中,点击Proxy -> Reverse Proxies
,设置一个本地地址作为你的WebSocket服务器的透明代理,然后在你的new WebSocket(<address>)
中使用该地址(React Native的话),然后你就可以看到你的WebSocket连接出现在 Charles
我想检查通过 web sockets 的网络流量,我无法控制网络代码,因为这是一个二进制库,我没有源代码,所以 我无法在代码的网络部分执行任何 log/breakpoint。
我已经尝试使用最新版本的 CharlesProxy,它声称能够嗅探 websockets 但是当我尝试 url 并且甚至没有提到使用 websockets 的 api在从我的 iPhone.
调用的端点列表中我已验证 CharlesProxy 配置正确,因为即使在 SSL 下我也能够检查非 websocket 流量。
所以我的问题是:有没有人找到解决方案来检查使用 CharlesProxy 通过 websockets 的流量?
注意:我在使用 iOS9
时禁用了 ATS谢谢!
我终于找到了答案。
Charles 3.11.2 与 WebSocket 完美配合。
我使用 socketIO,所以我已经看到在协商阶段发送的 http 请求,但是 我错过了 websockets 流量。
一开始,socketIO尝试使用polling然后切换到使用websockets.
当您转到状态为 "Sending request body" 的请求时,websocket 流量是可见的,实际上是 wss:// 请求。
您甚至可以为此类流量设置专门的标签。其余消息将显示在此处。
PS1。确保您已正确连接到套接字,然后它会出现在 Charles 中。
PS2。我建议使用 socketIO 它是对像 websockets 这样的全双工流量的一个很好的增强。
更新: 显然 socket.io-client-swift v15.1.0 现在可以正确支持 SOCKS 代理。我还没有尝试过,但这意味着不再需要对红蜘蛛进行这些手动编辑。
接受的答案似乎不适用于 iOS 设备上的 Socket.IO。
Socket.IO-Client-Swift 的最新版本(撰写本文时为 15.0.0)在 iOS/OS X 上使用 Starscream 作为 WebSockets。
好消息是红蜘蛛支持 SOCKS 代理:
Socket.IO 不公开 Starscream websocket 或提供任何 API 来启用 SOCKS 代理行为。
红蜘蛛内置的 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 路由所有 websockets 流量。
然后您需要确保在 iOS 中配置了 HTTP 代理设置(因为 HTTP 和 SOCKS 将使用相同的 IP),在 Charles 中启用了 SOCKS 代理,并且端口匹配上面代码中的端口(默认 8889)。
感谢乔纳森·埃利斯的非常有用的回答! 我正在使用 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 中启用了 socks 代理。
再次感谢!
找到解决方法:
尝试后,我得出结论,尽管 iOS 模拟器遵循 HTTP 的系统代理设置,但未遵循 WebSocket。也不遵循 Socks5 代理设置。
但是,我们可以在Charles中使用Reverse Proxies
来强制模拟器使用它。
在Charles中,点击Proxy -> Reverse Proxies
,设置一个本地地址作为你的WebSocket服务器的透明代理,然后在你的new WebSocket(<address>)
中使用该地址(React Native的话),然后你就可以看到你的WebSocket连接出现在 Charles