使用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)

  

 

posted @ 2014-11-18 12:02  tommy.yu  阅读(586)  评论(0编辑  收藏  举报