2011-10-20 14 views
7

Actualmente estoy escribiendo un servidor de modelo de despacho básico basado en la biblioteca de Python Eventlet (http://eventlet.net/doc/). Después de mirar los documentos WSGI en Eventlet (http://eventlet.net/doc/modules/wsgi.html), puedo ver que la función eventlet.wsgi.server registra el encabezado x-forward-for además del cliente Dirección IP.Obtención de la dirección IP del cliente desde una aplicación WSGI utilizando Eventlet

Sin embargo, la forma de obtener esto es adjuntar un objeto similar a un archivo (el valor por defecto que es sys.stderr) y luego hacer que el servidor lo canalice hacia ese objeto.

Me gustaría poder obtener la IP del cliente desde la propia aplicación (es decir, la función que tiene start_response y environ como parámetros). De hecho, una clave de entorno sería perfecta para esto. ¿Hay alguna manera de obtener la dirección IP simplemente (es decir, a través del diccionario del entorno o similar), sin tener que recurrir a redirigir el objeto de registro de alguna manera?

Respuesta

14

Lo que usted quiere está en el wsgi environ, específicamente environ['REMOTE_ADDR'].

Sin embargo, si hay un proxy involucrado, entonces REMOTE_ADDR será la dirección del proxy, y la dirección del cliente se incluirá (lo más probable) en HTTP_X_FORWARDED_FOR.

Aquí es una función que debe hacer lo que quiera, para la mayoría de los casos (todo el crédito a Sævar):

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

Se puede ver fácilmente lo que está incluido en el Environ wsgi escribiendo un wsgi sencilla aplicación y señalando un navegador en ella, por ejemplo:

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) 

y la combinación de los dos ...

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) 
+1

Gracias Marty, de hecho fue mi siguiente movimiento para hacer realmente lo que sugirió en su segundo fragmento. Gracias también por señalar la información del proxy, si hubiera puesto un equilibrador de carga al frente, esto seguramente habría causado cierta confusión. Después de consultar la especificación de WSGI [link] (http://www.python.org/dev/peps/pep-0333/#environ-variables), veo que REMOTE_ADDR no es una variable obligatoria, que probablemente fue la fuente de mi confusión! –

+0

Estaba leyendo un poco de documentación en este encabezado, y me parece que la dirección IP del cliente sería la primera dirección IP en X-Forwarded-For. Así que ese último bit en la primera devolución debería ser probablemente '.split (',') [0] .strip()'. Referencia: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For –

Cuestiones relacionadas