.Net下HTTP访问穿越多层代理的方法以及代理服务器的验证 转载
https://blog.williamgates.net/2006/07/aspdotnet-through-multi-proxy/
首先,通过普通的匿名透明代理的方法,是直接使用Socket发送GET命令,只不过与GET普通网站稍有不同罢了
直接访问:
1
2
3
4
5
6
7
8
9
10
11
|
GET / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
If-Modified-Since: Thu, 06 Jul 2006 15:39:53 GMT
If-None-Match: "1172d9-381c-44ad2ec9"
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: www.redhat.com
Connection: Keep-Alive
Cookie: s_vi=[CS]v1|44AAA05400004577-A170C060000008A[CE]; Apache=61.147.159.196.23241152032846747
|
通过本机CCproxy:
1
2
3
4
5
6
7
8
|
GET / HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*
Accept-Language: zh-cn
UA-CPU: x86
Proxy-Connection: Keep-Alive
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
Host: www.redhat.com
Cookie: s_vi=[CS]v1|44AAA05400004577-A170C060000008A[CE]; Apache=61.147.159.196.23241152032846747
|
可以看出来,只要给代理服务器发送正确的请求地址即可,不需要程序上特殊的变化。
事实上,对于不使用代理服务器的场合,你可以直接向某HTTP服务器发送GET /,而这在使用代理时不行,需要说明详细地址或者标明Host: www.redhat.com
对于两层代理,就有所不同了
首先要给sproxy发送一个CONNECT指令,令其去连接某公众网代理(这里称为proxy2),然后通过这个Socket连接发送GET指令给proxy2。这里对sproxy(以后称proxy1)有一个要求,即必须支持CONNECT,也就是说必须是一个HTTP Tunnel,或者说支持HTTPS。
由于一开始设置上的问题,我本以为返回HTTP 1.0的CCProxy不支持这样的方式,因为据说HTTP 1.0就不能支持HTTPS,连接一次,发送了数据一定会断开(一开始的测试中的确如此)。后来查阅资料才知道,HTTP 1.0只是默认不使用Connect: Keep-Alive的参数,事实上也是支持的,只要置上这个参数即可。
但实际使用中,发现不加上这个参数也是可以的(我对proxy1没有使用这个参数,可能是.net下的Socket类自动加上了)。
经过连续数天的测试,一直不能通过,问题集中在,给proxy2发送一次CONNECT命令,Socket就会断开,无法收到数据。这是典型的不支持HTTP Tunnel的表现,但是我一直怀疑是CCproxy和学校代理服务器的问题,没有发现根源所在。
因为我们访问sproxy需要用户名密码验证,我不得已才使用了CCProxy。后来,我又安装了一个代理服务器软件,发现其中只要使用“代理嵌套”(CCproxy叫作二级代理)的时候都需要HTTPS,我突然想到,会不会需要在CCproxy中设置?
于是,在CCproxy的设置-高级-二级代理中把代理类型设为HTTPS,使用proxy1做上级代理,果然成功。事实上,直接连接学校代理应该也是可以的,只是我还不知道如何在代理请求中发送用户验证信息(需要将验证信息截断为多个数据包,不能直接发送)。
代码如下,调试通过并成功运行了十多天了:
后台一个类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
public string Get_Socket_Request_uip(string ip)
{
Encoding ASCII = Encoding.Default;
//给Proxy2发送命令
string Con = "CONNECT " + ip + " HTTP/1.1
Connection: Keep-Alive
";
string Get = "HEAD http://www.RedHat.com/ HTTP/1.1
Host: www.RedHat.com
Pragma: no-cache
Connection: Close
";
Byte[] ByteCon = ASCII.GetBytes(Con);
Byte[] ByteGet = ASCII.GetBytes(Get);
Byte[] RecvBytes = new Byte[256];
Byte[] RecvBytes2 = new Byte[256];
string strRetPage = null;
string strRetCon = null;
//建立Socket
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//连接本地CCProxy
IPAddress hostip = IPAddress.Parse("127.0.0.1");
IPEndPoint ipend = new IPEndPoint(hostip, 808);
//设置超时,超过了就证明这个代理无效
s.SendTimeout = 20000;
s.ReceiveTimeout = 20000;
//这句话就是socket的Keep-Alive,我没有使用
//s.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
s.Connect(ipend);
try
{
//发送CONNECT命令
s.Send(ByteCon, ByteCon.Length, 0);
Int32 bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);
strRetCon = strRetCon + ASCII.GetString(RecvBytes, 0, bytes);
if (strRetCon.Contains("200"))
{
s.Send(ByteGet, ByteGet.Length, 0);
Int32 bytes2 = s.Receive(RecvBytes2, RecvBytes2.Length, 0);
strRetPage = strRetPage + ASCII.GetString(RecvBytes2, 0, bytes2);
//本来这里会循环接收数据(本来发送的不是HEAD而是GET,取整个页面),后来发现有时候这会导致断线,就去掉了,只用HEAD命令取返回的HTTP Head
/*while (bytes2 > 0)
{
bytes2 = s.Receive(RecvBytes2, RecvBytes2.Length, 0);
strRetPage = strRetPage + ASCII.GetString(RecvBytes2, 0, bytes2);
}*/
}
}
catch
{
break;
}
finally
{
s.Shutdown(SocketShutdown.Both);
s.Close();
}
return strRetPage;
}
|
前台的调用方法(已经使用证则表达式在别处的网页中抓取到待检测的代理列表,在matches数组中):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public void TestProxy()
{
int r = 0;
try
{
foreach (Match i in matches)
{
string ip = i.Result("${ip}");
string port = i.Result("${port}");
try
{
//这里的hc是后台那个类,myhttpclient
string result = hc.Get_Socket_Request_uip(ip + ":" + port);
if (result.Contains("200 OK"))
{
checkedproxy[r] = ip + ":" + port;
r = r + 1;
}
}
catch (TimeoutException)
{
continue;
}
catch
{
continue;
}
}
}
catch
{
break;
}
}
|
WebService代码就不给出了,就是调用这个方法而已。
大家应该可以看出,这里实际上通过了三层代理(CCproxy,proxy1,proxy2),所以,如果要通过n层代理,方法也是一样的,只要一层层的CONNECT下去就行,但要求前n-1层代理都要支持HTTP tunnel。
另外,在实际部署中使用这个程序,需要在Web.config中的system.web项下添加一行
1
|
<httpruntime executionTimeout="600"/>
|
否则超过10项的代理列表,几乎一定会超时的
.Net下HTTP访问穿越多层代理的方法以及代理服务器的验证 转载的更多相关文章
- nginx下禁止访问robots.txt的设置方法
关于robots.txt文件:搜索引擎通过一种程序robot(又称spider),自动访问互联网上的网页并获取网页信 息.您可以在您的网站中创建一个纯文本文件robots.txt,在这个文件中声明该网 ...
- CAS (6) —— Nginx代理模式下浏览器访问CAS服务器网络顺序图详解
CAS (6) -- Nginx代理模式下浏览器访问CAS服务器网络顺序图详解 tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 nginx版本: nginx-1. ...
- CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解
CAS (5) -- Nginx代理模式下浏览器访问CAS服务器配置详解 tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 nginx版本: nginx-1.9.8 ...
- CAS (3) —— Mac下配置CAS客户端经代理访问Tomcat CAS
CAS (3) -- Mac下配置CAS客户端经代理访问Tomcat CAS tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 nginx版本: nginx-1.9 ...
- Tomcat 下配置OpenLayers proxy.cgi代理
摘要:在OpenLayers访问WFS服务时,会遇到跨域的问题而导致服务无法访问.此时,需要在应用程序中设置代理,通过代理进行访问.本文介绍在tomcat进行proxy.cgi文件配置,以及在调用代理 ...
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...
- mac 下终端访问文件出现“Permission Denied”解决方案
mac 下终端访问文件出现“Permission Denied”解决方案: 一个文件有3种权限,读.写.可执行,你这个文件没有可执行权限,需要加上可执行权限. 1. 终端下先 cd到该文件的目录下 2 ...
- ENC28J60 + M430G2553,用uip搭建http服务器,解决“在XP系统下可以访问,在Win7下不能访问”的问题
近日,用ENC28J60,在M430G2553上搭建一个简单的HTTP服务器,结果发现在XP系统下可以访问,在Win7下不能访问,非常奇葩的问题. 通过抓包,如下图,计算机(IP地址为192.168. ...
- springboot集成下,mybatis的mapper代理对象究竟是如何生成的
前言 开心一刻 中韩两学生辩论. 中:端午节是属于谁的? 韩:韩国人! 中:汉字是谁发明的? 韩:韩国人! 中:中医是属于谁的? 韩:韩国人! 中:那中国人到底发明过什么? 韩:韩国人! 前情回顾 M ...
随机推荐
- C#打印
public partial class Form1 : Form { PrintDocument printDocument; StringReader lineReader = null; pub ...
- pull类型消息中间件-消息发布者(一)
消息集群架构 对于发送方来说的关键几要素 topic 消息的主题,由用户定义.类似于知乎的话题,Producer发送消息的时候需要指定发送到某一个topic下面,Consumer从某一个topic下面 ...
- linux下安装php的mcrypt拓展
安装步骤: 1,#wget http://museum.php.net/php5/php-5.3.3.tar.gz 2,解压:#tar -zxvf php-5.3.3.tar.gz 3,#cd ...
- Chapter 2 Open Book——29
Which left me with nothing to do but try to not look at him…unsuccessfully. 我没什么事情可以做但是我尝试不去看他,但是失败了 ...
- 免费数据库(SQLite、Berkeley DB、PostgreSQL、MySQL、Firebird、mSQL、MSDE、DB2 Express-C、Oracle XE)
SQLite数据库是中小站点CMS的最佳选择 SQLite 是一个类似Access的轻量级数据库系统,但是更小.更快.容量更大,并发更高.为什么说 SQLite 最适合做 CMS (内容管理系统)呢? ...
- $_SERVER 等超全局数组的用法 $_COOKIE $_GET $_SESSION
$_SERVER 服务器和执行环境信息 例如 $_SERVER['SERVER_NAME']; 当前运行脚本所在的服务器的主机名.如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定.$_G ...
- linux php安装
Linux下配置安装PHP环境 参考别人的做法,遇到问题上网查,下面就是安装步骤. 一.安装Apache2.2.221.到官网下载 http://httpd.apache.org/download. ...
- Xcode-App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.
在xcode中上报数据时候,logserver一直没有数据,后来发现控制台有一个提示: 找了半天是因为Xcode7禁止明码的HTTP请求,而自己使用的是Xcode7.2.1 解决办法:修改info.p ...
- shell初学
超简单的一段shell代码,查看电脑属性,删除无效安装包,查看天气.FYI #!/bin/bash echo -e '\n' echo "Hello,`whoami`" echo ...
- 用户id有则更新,无则添加 使用replace into (代替 insert into)
app登录成功后,调用后台,更新channel_id public function set_pushchannel($device,$channelid,$iv='' ) $sql = " ...