使用twisted.web实现代理服务器
简单的实现谷歌的代理:
架构就是下面这么简单。
=================
my server outside GFW | <----------------------> your browser visit my server at port 8080
=================
代码如下:
#coding=utf-8 from twisted.web import resource, server from twisted.internet import reactor,endpoints from twisted.python import log import urllib2 import urllib import sys from twisted.web.util import Redirect #log.startLogging(sys.stdout) def get_redirect_url(url, prefix): if not url: return '' index = url.find(prefix) if index>-1: index2 = url.find('&sa=') return url[index:index2] return url class router(resource.Resource): def getChild(self, path, request): url = r'https://www.google.com' if path=="": return Index(url) else: new_url = str(request.uri) new_url = get_redirect_url(new_url,'http://') new_url = get_redirect_url(new_url,'https://') if new_url and (new_url.find('http://')>-1 or new_url.find('https://')>-1): return Redirect(new_url) return Index(url+ request.uri) class Index(resource.Resource): def __init__(self, url): self.url = url def render_GET(self, request): headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'} req = urllib2.Request(self.url,headers=headers) res = urllib2.urlopen(req) return res.read() if __name__=='__main__': rsc = router() f = server.Site(rsc) endpoints.serverFromString(reactor, 'tcp:8080').listen(f) reactor.run()
干脆做成启动任务,参考这里:http://www.cnblogs.com/Tommy-Yu/p/4105942.html.
发现一个问题,就是,神马链接都给代理了,这样不行,搜索出来的链接得丢出去。改下router的getChild的实现。否则若是你的vps计费,流量得耗光。
解决这个问题,要把链接给redirect出去。方案有两种:
在不同的地方使用不同的方法:
- 在 getChild 中使用 twisted.web.util.Redirect
- 在 render 中使用 twisted.web.util.redirectTo
在 getChild 中:
class Index(Resource): def getChild(self, path, request): from twisted.web.util import Redirect return Redirect('/login')
在 render render_GET render_POST 中:
class Index(Resource): def render(self, request): from twisted.web.util import redirectTo return redirectTo('/login', request)