Django как обратный прокси

Мое клиент-серверное приложение в основном основано на http-сервере специального назначения, который взаимодействует с клиентом в стиле Ajax, т.е. графический интерфейс клиента обновляется при асинхронных циклах HTTP-запроса/ответа.

Возможность развития специального http-сервера ограничена, и по мере роста приложения требуется все больше и больше стандартных функций, которые, например, предоставляет Django.

Следовательно, я хотел бы добавить приложение Django в качестве фасада/обратного прокси-сервера, чтобы скрыть нестандартный сервер специального назначения и иметь возможность получать выгоду от Django. Я хотел бы использовать приложение Django в качестве шлюза и не использовать http-redirect из соображений безопасности и скрыть сложность.

Однако меня беспокоит то, что туннелирование трафика через Django на сервере может снизить производительность. Это обоснованное беспокойство?

Есть ли альтернативное решение проблемы?


person Bernhard    schedule 07.03.2011    source источник


Ответы (2)


Обычно в производстве вы размещаете Django за веб-контейнером, таким как Apache httpd или nginx. У них есть модули, предназначенные для проксирования запросов (например, proxy_pass для location в nginx). Они дают вам некоторые дополнительные возможности, такие как кэширование, если вам это нужно. По сравнению с проксированием через конвейер запросов приложения Django это может сэкономить время разработки, обеспечивая при этом более высокую производительность. Однако при использовании подобного решения вы жертвуете возможностью полностью манипулировать запросом или проксируемым ответом.

Для локального тестирования с помощью ./manage.py runserver я добавляю шаблон URL через urls.py в разделе if settings.DEBUG: .... Вот используемый мной код функции представления, который поддерживает GET, PUT и POST с использованием библиотеки requests Python: https://gist.github.com/JustinTArthur/5710254

person Justin Turner Arthur    schedule 04.06.2013
comment
Я не хотел настраивать, и сервер nginx просто делал это. Но я получил его в производстве. Я хотел отразить поведение proxy_pass. Поэтому я использовал ваш скрипт с этим очень простым промежуточным ПО с вашим представлением. Спасибо - person Patrick Bassut; 17.11.2015

Я пошел дальше и построил простой прототип. Это было относительно просто, мне просто нужно было настроить представление, которое отображает все URL-адреса, которые я хочу перенаправить. Функция просмотра выглядит примерно так:

def redirect(request):
    url = "http://%s%s" % (server, request.path)
    # add get parameters
    if request.GET:
        url += '?' + urlencode(request.GET)

    # add headers of the incoming request
    # see https://docs.djangoproject.com/en/1.7/ref/request-response/#django.http.HttpRequest.META for details about the request.META dict
    def convert(s):
        s = s.replace('HTTP_','',1)
        s = s.replace('_','-')
        return s

    request_headers = dict((convert(k),v) for k,v in request.META.iteritems() if k.startswith('HTTP_'))
    # add content-type and and content-length
    request_headers['CONTENT-TYPE'] = request.META.get('CONTENT_TYPE', '')
    request_headers['CONTENT-LENGTH'] = request.META.get('CONTENT_LENGTH', '')

    # get original request payload
    if request.method == "GET":
        data = None
    else:
        data = request.raw_post_data

    downstream_request = urllib2.Request(url, data, headers=request_headers)
    page = urllib2.urlopen(downstream_request)
    response = django.http.HttpResponse(page)
    return response

Так что это на самом деле довольно просто, и производительность достаточно высока, особенно если перенаправление идет на петлевой интерфейс на том же хосте.

person Bernhard    schedule 07.04.2011
comment
В кодлете, который вы используете, заголовки не передаются. есть ли простой способ передать входящий запрос как есть. Я делаю что-то подобное и хочу использовать заголовки o-auth. Но вам нужно чистое решение, которое передает все заголовки (для проверки в будущем). Итак, по сути, я хочу написать обратный прокси-сервер, но перенаправить URL-адреса специального назначения, остальное обслуживать из моего приложения django. - person pranshus; 12.08.2014
comment
Я обновил код примера, чтобы включить передачу заголовков HTTP. Возможно, вам потребуется открыть или изменить некоторые из исходных заголовков запроса, например. «ХОСТ», «СОЕДИНЕНИЕ». - person Bernhard; 18.08.2014