使用Eventlet从WSGI应用程序获取客户端IP地址

Mic*_*ore 9 python wsgi eventlet

我目前正在编写一个基于Python Eventlet库的基本调度模型服务器(http://eventlet.net/doc/).看过Eventlet上的WSGI文档(http://eventlet.net/doc/modules/wsgi.html),我可以看到eventlet.wsgi.server函数除了客户端之外还记录了x-forwarded-for头文件IP地址.

但是,获取此方法的方法是附加一个类文件对象(默认为sys.stderr),然后将该服务器管道连接到该对象.

我希望能够从应用程序本身获取客户端IP(即具有start_response和environ作为参数的函数).实际上,环境密钥对此非常完美.有没有办法简单地获取IP地址(即通过环境字典或类似),而不必采取某种方式重定向日志对象?

Mar*_*rty 15

你想要的是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']
Run Code Online (Sandbox Code Playgroud)

您可以通过编写一个简单的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)
Run Code Online (Sandbox Code Playgroud)

并将两者结合起来......

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)
Run Code Online (Sandbox Code Playgroud)