Как мне использовать ReverseProxyProtocol - PullRequest
1 голос
/ 17 октября 2010

У меня есть следующее:

  1. Мой веб-сервер работает на витой
  2. Мой комет-сервер, он же орбитальный

Обратите внимание, что 1 и 2 отличаютсяпроцессы.

По сути, я хочу, чтобы 1 и 2 использовали один и тот же порт.Запрос http://mysite.com/a/b/c должен идти на веб-сервер, а все, что начинается с http://mysite.com/orbited/, должно отправляться на орбитальный сервер, т. Е. (http://mysite.com/orbited/a/b/c => сделать запрос к http://mysite.com:12345/a/b/c и вернутьсяэто).

Это то, что у меня сейчас есть:

# Reverse Proxy
class OrbitedResource(Resource):
    isLeaf = True

    def __init__(self, orbited_url='http://127.0.0.1:12345'):
        self.orbited = orbited_url
        Resource.__init__(self)

    def render_GET(self, request):

        def callback(html):
            request.write(html)
            request.finish()

        def errback(failure, *args):
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
            request.write(failure.getErrorMessage())
            request.finish()

        request.setHeader('Connection', 'close')

        # TODO find cleaner way to do this:
        # Currently request.uri is "/orbited/....", you must trim it
        target_uri = request.uri.replace('/orbited', '') 
        final_uri = self.orbited + target_uri
        print "final_uri is", final_uri

        deferred = getPage(final_uri)
        deferred.addCallbacks(callback, errback)
        return server.NOT_DONE_YET


class SimpleRoutingResource(Resource):
    isLeaf = False

    def __init__(self, wsgiApp):
        Resource.__init__(self)
        self.WSGIApp = wsgiApp
        self.orbitedResource = OrbitedResource()

    def getChild(self, name, request):
        if name == "orbited":
            request.prepath.pop()
            print "Simple request.path is", request.path
            return self.orbitedResource
        else: 
            request.prepath.pop()
            request.postpath.insert(0,name)
            return self.WSGIApp

# Attaching proxy + django 
log_dir = './.log'
if not os.path.exists(log_dir):
    os.makedirs(log_dir)
reactor.listenTCP(DJANGO_PORT, server.Site(SimpleRoutingResource(WSGIRoot), 
        logPath=os.path.join(log_dir, '.django.log')))

В настоящее время это работает .Тем не менее, я вижу, что есть класс с именем ReverseProxyProtocol, и я пробовал его со следующей модификацией:

class SimpleRoutingResource(Resource):
    isLeaf = False

    def __init__(self, wsgiApp):
        Resource.__init__(self)
        self.WSGIApp = wsgiApp

    def getChild(self, name, request):
        if name == "orbited":
            request.prepath.pop()
            print "Simple request.path is", request.path, name
            return ReverseProxyResource( 'http://localhost', 12345, name )
        else: 
            request.prepath.pop()
            request.postpath.insert(0,name)
            return self.WSGIApp

Это НЕ работает.Я вставил много отпечатков в витой класс reverseProxyResource и обнаружил следующее:

  1. Учитывая http://mysite.com/orbited/a/b/c
  2. OrbitedResource будет продолжать вызывать ReverseProxyResource с getChild до тех пор, пока c
  3. к тому времени, когда вы доберетесь до c, URL-адрес запутается, и класс клиента, вызывающий орбитальный сервер, будет неверным
  4. Я попытался установить isLeaf = True в ReverseProxyResource, но безрезультатно.

Кто-нибудь может подсказать мне более эффективный способ написания getPage?Мне действительно нужно использовать ReverseProxyResource, если это такой черный ящик в природе?

1 Ответ

0 голосов
/ 17 октября 2010

Самый чистый способ - поместить что-то вроде nginx перед обоими серверами.

...