summaryrefslogtreecommitdiff
path: root/paste/proxy.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2006-08-24 16:56:56 +0000
committerianb <devnull@localhost>2006-08-24 16:56:56 +0000
commit69405370d260e231a0df58d359b49462f01c9801 (patch)
treef4c7d51cd5ab82cb6730a6e7e454930c1cc03060 /paste/proxy.py
parent99d395d6b3d7a41f47e532eb2bf90197f92e69f6 (diff)
downloadpaste-69405370d260e231a0df58d359b49462f01c9801.tar.gz
Added TransparentProxy
Diffstat (limited to 'paste/proxy.py')
-rw-r--r--paste/proxy.py69
1 files changed, 69 insertions, 0 deletions
diff --git a/paste/proxy.py b/paste/proxy.py
index c8075e7..aff824d 100644
--- a/paste/proxy.py
+++ b/paste/proxy.py
@@ -121,3 +121,72 @@ def make_proxy(global_conf, address, allowed_request_methods=""):
from paste.deploy.converters import aslist
allowed_request_methods = aslist(allowed_request_methods)
return Proxy(address, allowed_request_methods=allowed_request_methods)
+
+
+class TransparentProxy(object):
+
+ """
+ A proxy that sends the request just as it was given, including
+ respecting HTTP_HOST, wsgi.url_scheme, etc.
+
+ This is a way of translating WSGI requests directly to real HTTP
+ requests. All information goes in the environment; modify it to
+ modify the way the request is made.
+ """
+
+ def __init__(self):
+ pass
+
+ def __call__(self, environ, start_response):
+ scheme = environ['wsgi.url_scheme']
+ if scheme == 'http':
+ ConnClass = httplib.HTTPConnection
+ elif scheme == 'https':
+ ConnClass = httplib.HTTPSConnection
+ else:
+ raise ValueError(
+ "Unknown scheme %r" % scheme)
+ if 'HTTP_HOST' not in environ:
+ raise ValueError(
+ "WSGI environ must contain an HTTP_HOST key")
+ host = environ['HTTP_HOST']
+ conn = ConnClass(host)
+ headers = {}
+ for key, value in environ.items():
+ if key.startswith('HTTP_'):
+ key = key[5:].lower().replace('_', '-')
+ headers[key] = value
+ headers['host'] = host
+ if 'REMOTE_ADDR' in environ:
+ headers['x-forwarded-for'] = environ['REMOTE_ADDR']
+ if environ.get('CONTENT_TYPE'):
+ headers['content-type'] = environ['CONTENT_TYPE']
+ if environ.get('CONTENT_LENGTH'):
+ length = int(environ['CONTENT_LENGTH'])
+ body = environ['wsgi.input'].read(length)
+ else:
+ body = environ['wsgi.input'].read(length)
+ length = len(body)
+
+ path = (environ.get('SCRIPT_NAME', '')
+ + environ.get('PATH_INFO', ''))
+ if 'QUERY_STRING' in environ:
+ path += '?' + environ['QUERY_STRING']
+ conn.request(environ['REQUEST_METHOD'],
+ path, body, headers)
+ res = conn.getresponse()
+ headers_out = []
+ for header, value in res.getheaders():
+ if header.lower() not in filtered_headers:
+ headers_out.append((header, value))
+
+ status = '%s %s' % (res.status, res.reason)
+ start_response(status, headers_out)
+ # @@: Default?
+ length = res.getheader('content-length')
+ if length is not None:
+ body = res.read(int(length))
+ else:
+ body = res.read()
+ conn.close()
+ return [body]