diff options
author | ianb <devnull@localhost> | 2006-02-03 09:12:59 +0000 |
---|---|---|
committer | ianb <devnull@localhost> | 2006-02-03 09:12:59 +0000 |
commit | 1666cfc7d9a5dc59e81fe0f2fc9ae407ec60d999 (patch) | |
tree | e903cbd790c1be42644947712d5666ae205d1633 /paste/proxy.py | |
parent | a4a76101efeed6833e239221397ec8f6035beeee (diff) | |
download | paste-1666cfc7d9a5dc59e81fe0f2fc9ae407ec60d999.tar.gz |
Added a simple and lightly tested proxy app
Diffstat (limited to 'paste/proxy.py')
-rw-r--r-- | paste/proxy.py | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/paste/proxy.py b/paste/proxy.py new file mode 100644 index 0000000..8f43718 --- /dev/null +++ b/paste/proxy.py @@ -0,0 +1,75 @@ +""" +An application that proxies WSGI requests to a remote server. + +TODO: + +* Send ``Via`` header? It's not clear to me this is a Via in the + style of a typical proxy. + +* Other headers or metadata? I put in X-Forwarded-For, but that's it. + +* Signed data of non-HTTP keys? This would be for things like + REMOTE_USER. + +* Something to indicate what the original URL was? The original host, + scheme, and base path. + +* Rewriting ``Location`` headers? mod_proxy does this. + +* Rewriting body? (Probably not on this one -- that can be done with + a different middleware that wraps this middleware) +""" + +import httplib +import urlparse + +class Proxy(object): + + def __init__(self, address): + self.address = address + self.parsed = urlparse.urlsplit(address) + self.scheme = self.parsed[0].lower() + self.host = self.parsed[1] + + def __call__(self, environ, start_response): + if self.scheme == 'http': + ConnClass = httplib.HTTPConnection + elif self.scheme == 'https': + ConnClass = httplib.HTTPSConnection + else: + raise ValueError( + "Unknown scheme for %r: %r" % (self.address, self.scheme)) + conn = ConnClass(self.host) + headers = {} + for key, value in environ.items(): + if key.startswith('HTTP_'): + key = key[5:].lower().replace('_', '-') + if key == 'host': + continue + headers[key] = value + headers['host'] = self.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 = '' + print (environ['REQUEST_METHOD'], + environ['PATH_INFO'], + body, headers) + conn.request(environ['REQUEST_METHOD'], + environ['PATH_INFO'], + body, headers) + res = conn.getresponse() + # @@: 2.4ism: + headers_out = res.getheaders() + status = '%s %s' % (res.status, res.reason) + start_response(status, headers_out) + # @@: Default? + length = res.getheader('content-length') + body = res.read(int(length)) + conn.close() + return [body] |