Getting client IP address from WSGI application using Eventlet

I am currently writing a base dispatch model server based on the Python Eventlet library (http://eventlet.net/doc/). After looking at the WSGI documents on the Eventlet (http://eventlet.net/doc/modules/wsgi.html), I see that the function eventlet.wsgi.server registers the x-forwarded-for header in addition to the client's IP address.

However, the way to get this is to attach a file-like object (by default it is sys.stderr), and then transfer the server channel to this object.

I would like to be able to get the client IP address inside the application itself (i.e. a function that has start_response and environment parameters as parameters). Indeed, an environmental key would be ideal for this. Is there a way to get the IP address simply (that is, through an environmental dictionary or similar) without resorting to redirecting the log object in any way?

+7
source share
1 answer

What do you want in wsgi environ , in particular environ['REMOTE_ADDR'] .

However, if there is a connected proxy, then REMOTE_ADDR will be the proxy address, and the client address will be included (most likely) in HTTP_X_FORWARDED_FOR .

Here is a function that should do what you want in most cases (all Sævar loans):

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

You can easily see what is included in the wsgi environment by writing a simple wsgi application and pointing the browser to it, for example:

 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) 

And the union of the two ...

 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) 
+14
source

All Articles