#!/usr/bin/env python from gevent import monkey monkey.patch_all() import sys import redis import urllib2 import traceback from cgi import escape # -- gsdproxy # gevent simple dynamic reverse proxy # ncode@karoly:~$ redis-cli # redis> set URL::MAP::: martinez.io # OK # based on: https://bitbucket.org/denis/gevent/src/14cdc044afd0/examples/webproxy.py # -- ncode PORT = 8000 def application(env, start_response): rds = redis.Redis() method = env['REQUEST_METHOD'] http_host = env['HTTP_HOST'] path = env['PATH_INFO'] path = "http://%s/" % rds.get("URL::MAP::%s" % http_host) if env['PATH_INFO']: path += env['PATH_INFO'] if env['QUERY_STRING']: path += '?' + env['QUERY_STRING'] path = path.lstrip('/') if method == 'GET': return proxy(path, start_response) elif method == 'POST': start_response('404 Not Found', []) else: start_response('501 Not Implemented', []) def proxy(path, start_response): try: try: response = urllib2.urlopen(path) except urllib2.HTTPError: response = sys.exc_info()[1] print ('%s: %s %s' % (path, response.code, response.msg)) headers = [(k, v) for (k, v) in response.headers.items()] except Exception: ex = sys.exc_info()[1] sys.stderr.write('error while reading %s:\n' % path) traceback.print_exc() tb = traceback.format_exc() start_response('502 Bad Gateway', [('Content-Type', 'text/html')]) error_str = escape(str(ex) or ex.__class__.__name__ or 'Error') return ['

%s

%s

%s
' % (error_str, escape(path), escape(tb))] else: start_response('%s %s' % (response.code, response.msg), headers) data = response.read() return [data] if __name__ == '__main__': from gevent.pywsgi import WSGIServer print 'Serving on %s...' % PORT WSGIServer(('0.0.0.0', PORT), application).serve_forever()