我的项目是.net 7.0,使用httpclient访问互联网上的rest api服务,但是这个服务需要通过代理服务器才能访问,于是我设置了代理,代码如下
var webProxy = new WebProxy("address", false);
var proxyHttpClientHandler = new HttpClientHandler
{
Proxy = webProxy,
UseProxy = true
};
ICredentials credential = new NetworkCredential("user001", "psw");
webProxy.Credentials = credential;
httpClient = new HttpClient(proxyHttpClientHandler);
通过get方法抓取测试网页可以正常返回html内容,说明代理工作正常。
通过post方法,调用rest api则经常失败(不是每次都失败,这点也不太理解),提示“连接被断开”错误。
检查代理服务器日志发现,每次post,实际产生两个请求,一个是所谓的preflight request,对于这个请求,代理服务器日志显示407错误,并且无访问者的username,说明没有携带Credential,对于第二个请求,日志则显示正常转发,并且有访问者的username,说明携带了Credential信息。
我的代理服务器是ubuntu+squid。两条日志信息如下
TCP_DENIED/407 3954 CONNECT api.xxx.com:443 - HIER_NONE/- text/html
TCP_TUNNEL/200 2653 CONNECT api.xxx.com:443 user001 HIER_DIRECT/100.18.6.192
补充一下,具体的错误如下:
InnerException {"Unable to read data from the transport connection: 远程主机强迫关闭了一个现有的连接。."} System.Exception {System.IO.IOException}
SocketErrorCode ConnectionReset System.Net.Sockets.SocketError
先谢谢各位的回答,我在stackoverflow上找到了部分答案,那就是preflight request请求返回407是http代理协议的正常步骤之一!所以高度怀疑是gfw导致的问题,于是我将程序部署到国外,一切正常了。那么问题变为:如何绕开gfw?因为Get请求一直正常,但Post就会被断开连接。所以代理服务器的ip是没有被彻底屏蔽的。