Получение IP-адреса клиента из приложения WSGI с помощью Eventlet - PullRequest
8 голосов
/ 20 октября 2011

В настоящее время я пишу сервер базовой модели диспетчеризации на основе библиотеки Python Eventlet (http://eventlet.net/doc/). Посмотрев документы WSGI на Eventlet (http://eventlet.net/doc/modules/wsgi.html),), я вижу, что функция eventlet.wsgi.server регистрирует x-заголовок forwarded-for в дополнение к IP-адресу клиента.

Однако способ получить это - присоединить файлоподобный объект (по умолчанию это sys.stderr), а затем получить серверный канал, которыйэтот объект.

Я хотел бы иметь возможность получить IP-адрес клиента из самого приложения (т. е. функции, которая имеет параметры start_response и environment в качестве параметров). Действительно, для этого идеально подойдет ключ окружения.Есть ли способ получить IP-адрес просто (т. е. через словарь окружения или аналогичный), не прибегая к каким-либо способам перенаправления объекта журнала?

1 Ответ

15 голосов
/ 20 октября 2011

То, что вы хотите, находится в среде wsgi , в частности environ['REMOTE_ADDR'].

Однако, если задействован прокси, то REMOTE_ADDR будет адресом прокси, и адрес клиента будет включен (скорее всего) в HTTP_X_FORWARDED_FOR.

Вот функция, которая должна делать то, что вы хотите, в большинстве случаев (все кредиты Sævar ):

def get_client_address(environ):
    try:
        return environ['HTTP_X_FORWARDED_FOR'].split(',')[-1].strip()
    except KeyError:
        return environ['REMOTE_ADDR']

Вы можете легко увидеть, чтовключите в среду wsgi, написав простое приложение wsgi и указав на него браузер, например:

from eventlet import wsgi
import eventlet

from pprint import pformat

def show_env(env, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['%s\r\n' % pformat(env)]

wsgi.server(eventlet.listen(('', 8090)), show_env)

И объединяя два ...

from eventlet import wsgi
import eventlet

from pprint import pformat

def get_client_address(environ):
    try:
        return environ['HTTP_X_FORWARDED_FOR'].split(',')[-1].strip()
    except KeyError:
        return environ['REMOTE_ADDR']

def show_env(env, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['%s\r\n\r\nClient Address: %s\r\n' % (pformat(env), get_client_address(env))]

wsgi.server(eventlet.listen(('', 8090)), show_env)
...