我正在使用 Boost:Asio 执行 HTTP GET(使用来自http://www.boost.org/doc/libs/1_50_0/doc/html/boost_asio/example/http/client/async_client.cpp的示例)
我没有在提琴手上看到我的请求(仅在 WireShark 上)我该如何更改?
我正在使用 Boost:Asio 执行 HTTP GET(使用来自http://www.boost.org/doc/libs/1_50_0/doc/html/boost_asio/example/http/client/async_client.cpp的示例)
我没有在提琴手上看到我的请求(仅在 WireShark 上)我该如何更改?
我有类似的问题关于如何解决它,所以我只是分享我的经验。据我所知,Asio
在套接字级别工作并且没有像@marcinj 指出的那样使用wininet,Fiddler 在wininet 上工作,但我们仍然可以通过使用Fiddler 作为代理来做到这一点。
首先,解释一下为什么它不能Boost:Asio
像解释 IE 上的流量一样工作?
另请参阅如何在 fiddler 中捕获套接字编程的发送和接收请求
Fiddler 将自己作为 HTTP 代理服务器插入到堆栈中。它依靠网络浏览器识别 PC 上配置了代理并通过该代理进行发送。您的代码未检测到要通过的代理发送 - 因此 Fiddler 将无法监控您的流量。
你有几个选择。
由于您是自己的 Windows,只需从使用直接套接字切换到使用WinInet HTTP API。它将为您进行自动代理检测,而无需您考虑。如果需要,它也会进行代理身份验证。
我推荐#1,因为这意味着您的代码将在真正的代理服务器(通常在企业网络上找到)存在的情况下工作,而 Fiddler 只会使用它。
我想还有第三个选项,您可以自动检测浏览器代理设置,然后为代理创建一个套接字,使用 HTTP 代理协议等……但这不是最佳做法。
二、怎么办?
有一个很好的例子关于传递代理地址来创建一个基于Socket(java.net.Proxy)或Configure a PHP/cURL Application to Use Fiddler的客户端,或者客户端应用程序不是你自己编写的,但如果你可以控制/配置您的客户端连接端点地址和端口,我们可以让 Fiddler 以任何方式拦截 HTTP(s) 流量(将 HTTP 请求重新路由为 HTTPS 请求或将 HTTPS 请求重新路由为 HTTPS 服务器的 HTTPS 请求)作为反向代理(需要一个参数)。Boost:asio
默认情况下,Fiddler 正在监听 8888。如果在浏览器中访问http://localhost:8888/,它会显示如下默认页面:
<!doctype html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Fiddler Echo Service</title></head><body style="font-family: arial,sans-serif;"><h1>Fiddler Echo Service</h1><br /><pre>GET / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
DNT: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _ga=GA9.1.123456789.1234567890
</pre>This page returned a <b>HTTP/200</b> response <br />Originating Process Information: <code>chrome:3628</code><br /><hr /><ul><li>To configure Fiddler as a reverse proxy instead of seeing this page, see <a href='http://fiddler2.com/r/?REVERSEPROXY'>Reverse Proxy Setup</a><li>You can download the <a href="FiddlerRoot.cer">FiddlerRoot certificate</a></ul></body></html>
OnBeforeRequest
(在规则 -> 自定义规则... Ctrl+R,FiddlerScript ),另请参阅修改请求或响应。//MessageBox.Show(oSession.fullUrl);
// string Session.fullUrl: Retrieves the complete URI, including protocol/scheme, in the form http://www.host.com/filepath?query.
//FiddlerObject.log("Session.fullUrl=" + oSession.fullUrl);
// string Session.url: Gets or sets the URL (without protocol) being requested from the server, in the form www.host.com/filepath?query."
//FiddlerObject.log("Session.url=" + oSession.url);
// string Session.PathAndQuery: Returns the path and query part of the URL. (For a CONNECT request, returns the host:port to be connected.)
//FiddlerObject.log("Session.PathAndQuery=" + oSession.PathAndQuery); // e.g. /filepath?query but host:port for a CONNECT request
// string Session.host: Gets/Sets the host to which this request is targeted. MAY include IPv6 literal brackets. MAY include a trailing port#.
// int Session.port: Returns the server port to which this request is targeted.
//FiddlerObject.log("Session.host=" + oSession.host + ", port=" + oSession.port);
// string Session.hostname: DNS Name of the host server (no port) targeted by this request. Will include IPv6-literal brackets for IPv6-literal addresses
//Gets/Sets the hostname to which this request is targeted; does NOT include any port# but will include IPv6-literal brackets for IPv6 literals.
FiddlerObject.log("Session: hostname=" + oSession.hostname + ", oRequest.pipeClient.LocalPort=" + oSession.oRequest.pipeClient.LocalPort);
//bool Fiddler.Utilities.isLocalhostname(sHostnameWithoutPort))
// Determines if the specified Hostname is a either 'localhost' or an IPv4 or IPv6 loopback literal
// Returns true if True if the sHostname is 127.0.0.1, 'localhost', or ::1. Note that list is not complete.
// Run Fiddler on your machine, and then add this block of code and test it works on the your same machine:
// Use the `curl http://localhost:8888/get`command or Using a browser, go to http://localhost:8888/get.
if (Utilities.isLocalhostname(oSession.hostname)) {
// By default, Fiddler is listening on 8888. Inspect what ports are being listened using proexp or netstat
// :: Lists the listening ports of a process with the specified image name including extension name(case-insensitive), fiddler.exe
// for /f "skip=1 tokens=2,9 delims=," %a in ('tasklist /fo csv /fi "IMAGENAME eq fiddler.exe" 2^>NUL') do (netstat -ano | findstr "PID LISTENING" | findstr "PID %a")
//oSession.host = "httpbin.org:443"; // oSession.oRequest.headers.UriScheme = "https";
oSession.fullUrl = "https://httpbin.org" + oSession.PathAndQuery;
}
您可以将使用实际 url 的预期响应与通过 url localhost 连接将请求转发到实际 url 的 Fiddler 代理(即 httpbin.org)的上述响应进行比较。
使用命令curl -v https://localhost:8888/get
(或浏览器),我们发现了一个错误
* schannel: sent initial handshake data: sent 182 bytes
* schannel: SSL/TLS connection with localhost port 8888 (step 2/3)
* schannel: failed to receive handshake, need more data
检查Wireshark中的流量,我发现 Fiddler 在客户端发送第一个 TLS 请求(Client Hello)后没有执行任何 HTTPS 握手。
Fiddler 输出日志:
18:28:44:5960 HTTPSLint> 警告:ClientHello 记录的长度为 508 字节。某些服务器在 ClientHello 大于 255 字节时存在问题。https://github.com/ssllabs/research/wiki/Long-Handshake-Intolerance
为了解决它,我们需要在规则脚本之外做:
将 Fiddler 配置为反向代理服务器,它将所有目的端口等于第二个参数!listen命令的请求转发到目标服务器。单击工具 > Fiddler 选项 > 连接。确保选中“允许远程客户端连接”。它使 fiddler 能够响应 HTTPS 的 SSL/TLS 握手请求。此步骤是持久配置。
在 HKEY_CURRENT_USER\SOFTWARE\Microsoft\Fiddler2 中创建一个名为 ReverseProxyForPort 的新 DWORD。将 DWORD 设置为 Fiddler 将重新路由入站流量的本地端口(通常是标准 HTTP 服务器的端口 80)。
:: reg query HKEY_CURRENT_USER\SOFTWARE\Microsoft\Fiddler2 /v ReverseProxyForPort
reg add HKEY_CURRENT_USER\SOFTWARE\Microsoft\Fiddler2 /v ReverseProxyForPort /t REG_DWORD /d 58080 /f && REM /f Force overwriting the existing registry entry without prompt to 58080
:: Deletes the registry key
:: REG DELETE HKEY_CURRENT_USER\SOFTWARE\Microsoft\Fiddler2 /v ReverseProxyForPort /f && REM /f Forces the deletion without prompt.
!listen *PORT [CERTHOSTNAME]*
Fiddler框中的脚本命令启动代理服务器侦听指定端口,方法是键入,其中 ServerHostName 是服务器的主机名;例如,对于https://Fuzzle/,您可以使用 fuzzle 作为服务器名称。QuickExec
!listen 443 ServerHostName
似乎没有必要在 Windows 注册表 (REGEDIT.exe) 中创建一个新的DWORD
命名ReverseProxyForPort
内部。HKEY_CURRENT_USER\SOFTWARE\Microsoft\Fiddler2
!listen *PORT [CERTHOSTNAME]*
在另一个端口上设置额外的侦听器,可选择由 HTTPS 证书保护
!listen 8889 !listen 4443 localhost !listen 444 secure.example.com
也可以看看
从用户的角度来看,向代理或反向代理服务器发送请求时:
- 代理- 需要两个参数:
1)获取什么和 2)哪个代理服务器使用中间- 反向代理- 需要一个参数:
1.) 获取什么反向代理从另一台服务器获取用户不知道的内容并返回结果,就好像它来自反向代理服务器 pspi 于 4 月 13 日 5:47 回答
以下代码用于
static function OnBeforeRequest(oSession:Fiddler.Session) {}
:if (oSession.HostnameIs("YYYY.azurewebsites.net")) oSession.host = "127.0.0.1:19703";
Fiddler 将入站请求从 HTTP 转换为 HTTPS 的最简单方法是在 OnBeforeRequest 中添加一些内容,例如:
if (oSession.HostnameIs("myhost") && (oSession.oRequest.pipeClient.LocalPort == 80)) { oSession.fullUrl = "https://" + oSession.url; }
当然,这假定 Fiddler 被配置为在端口 80 上运行,这是 HTTP 的默认端口。您可以在您喜欢的任何端口上运行它(例如,如果端口 80 已在使用中),但您需要更改客户端请求的 URL 中的端口,如果您可以这样做,您可能能够更改客户端以使用 HTTPS URL 开头。
Asio 在套接字级别工作并且不使用 wininet - 所以提琴手无法捕捉到它的流量。
我一直在寻找解决方案,要让 fiddler 与 asio 一起工作,您需要将其用作代理。要在提琴手中启用代理,请使用工具 -> Telerik Fiddler 选项 -> 连接。
要将代理服务器与 asio 一起使用,您需要使用其 IP 地址 + 端口而不是目标服务器。然后在 GET 中,您需要提供完整的目标 uri - 不仅是路径。如需更好的解释,请参见此处:如何向 boost::asio 添加代理支持?