用CONNECT方法突破HTTP代理服务器的扩展名封锁(python) (转)

转载地址

 

公司里的电脑是通过一台内部代理服务器上网的,为了节省带宽,对下载进行了限制。方法是过滤URL中的扩展名,如 'exe','rar','tar.gz'等,并且限制了连接时间,当连接时间超过2分钟就主动断开。这样平常就只能看看网页了,要下载就要申请,非常麻 烦。虽说可以通过“问号大法”来解决URL过滤,wget来解决断点续传,但这样还是不好,下大一点的文件或网速慢一点时,要断线好几十次。一次偶然的机 会发现公司的代理服务器没有限制CONNECT命令,哈哈,终于可以解决下载问题了。

通过向代理服务器发送CONNECT命令,可以让代理服务器和目标主机的目标端口建立一个连接,这样本机和目标主机就有了一个通道。从此以后向代理服务器发送命令就等于向目标主机发送命令。这和一般的GET方式不同,完全不受过滤机制的影响。先来看看两种方式的不同之处,

GET方式:

















socket.connect('HTTP代理服务器IP',HTTP代理服务器端口)















socket.send('GET http://XXX.XXX.XXX/XXX.EXE HTTP/1.1/r/n















HOST: XXX.XXX.XXX/r/n/r/n')
















CONNECT方式:

















socket.connect('HTTP代理服务器IP',HTTP代理服务器端口)















socket.send('CONNECT XXX.XXX.XXX:80 HTTP/1.1/r/n/r/n')















socket.recv(1024)















socket.send('GET /XXX.EXE HTTP/1.1/r/n















HOST: XXX.XXX.XXX/r/n/r/n')
















就是这么简单,下面就用python来完成编码。python有很多对http协议的封装库,如urllib2,httplib等。但我不知 urllib2如何设置connect方式的代理,懒得去研究了。所以直接用socket来实现。相对于C++,用python来操作socket是如此 的简单优雅。
pget.py:

















import socket















import sys































#如果参数<1则显示信息















if len(sys.argv)<2:















print 'proxyGet v0.3 /n/















Written by Wangfan/n/















Powered by Python 2.5/n/n/















Usage:/n/















pget [URL]'















sys.exit()































#URL处理函数,得到文件名、HOST、GET请求















def parseURL(url):















url=url.split('/')















file_name=url[-1].strip()















host=url[2]















del url[0]















del url[0]















del url[0]















header_get='/'+'/'.join(url)















return (file_name,host,header_get)































urlInfo=parseURL(sys.argv[1])















print '***pget v0.3***/n/n/















File Name: %s/n/















From: %s/n/















GET: %s/n/















' %(urlInfo[0],urlInfo[1],urlInfo[2])































#确认可以开始下载















input_char=raw_input('ok?(press "y" to start,press other to exit):')















if input_char!='y':















sys.exit()































#初始化socket















s=socket.socket()































#连接代理服务器















s.connect(('10.100.1.206',3128))































#发送CONNECT命令,连接目标主机















s.send('CONNECT '+urlInfo[1]+':80 HTTP/1.1/n/n')































#得到回应















print 'Proxy:',s.recv(1024).strip()































#发送下载请求和头信息















s.send('GET '+urlInfo[2]+' HTTP/1.1/r/n/















Host: '+urlInfo[1]+'/r/n/















User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3/r/n/















Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8/r/n/















Accept-Language: en-us,en;q=0.5/r/n/















Accept-Encoding: gzip,deflate/r/n/















Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7/r/n/















Keep-Alive: 300/r/n/















Proxy-Connection: keep-alive/r/n/r/n')















r=''















headers=''















content_length=0















header_end=False































#循环读取,处理回应的头信息和内容















while True:















r+=s.recv(1)















downloaded=len(r)















if header_end==False:















if r.find('/r/n/r/n')!=-1:















headers=r.split('/r/n/r/n')[0]















print headers















for header in headers.split('/r/n'):















if header.split(':')[0]=='Content-Length':















content_length=int(header.split(':')[-1])















if header.split(':')[0]=='Location':















sys.exit()















r=''















header_end=True















if content_length==0:















sys.exit()















if downloaded%1024==0:















#输出下载进度















print '/r[',int((downloaded/1024)/float(content_length/1024)*100),'%]',downloaded/1024,'KB /',content_length/1024,'KB',































#如果已下载的内容长度等于头信息中长度则跳出















if downloaded==content_length:















break































#保存文件















fp=open(urlInfo[0],'wb')















fp.write(r)















fp.close()















s.close()















sys.exit()

















由于不想占用过多的带宽,所以没有加入多线程。但是,可以扩展的地方还有很多,比如断点续传等,以后有空再完善吧,先做个可以用的原型:)

 

你可能感兴趣的:(python,服务器,header,url,input,扩展)