Created
January 21, 2011 03:21
-
-
Save amcgregor/789193 to your computer and use it in GitHub Desktop.
A transparent caching proxy server built using WSGI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
"""A transparent caching proxy. | |
To use, simply create a directory and run this script a la: | |
./caching-proxy.py cache | |
Then point your browser's HTTP proxy at localhost:8888. | |
Everything requested will be cached (regardless of no-cache headers). | |
To clear the cache, simply nuke the contents of the folder. | |
""" | |
import os | |
import sys | |
import hashlib | |
import httplib | |
from wsgiref.simple_server import make_server | |
def filename(method, path): | |
return os.path.join(sys.argv[1], hashlib.sha256(method + ' ' + path).hexdigest()) | |
def proxy(environ, start_response): | |
fn = filename(environ['REQUEST_METHOD'], environ['PATH_INFO']) | |
status = '200 OK' | |
headers = [] | |
body = None | |
if os.path.exists(fn): | |
print "Cache hit:", fn | |
data = open(fn, 'r').readlines() | |
status = data[0].strip() | |
j = 0 | |
for i, header in enumerate(data[1:]): | |
if header.strip() == "": | |
j = i + 1 | |
break | |
headers.append(tuple(header.strip().split(':', 1))) | |
body = data[j+1:] | |
else: | |
print "Cache miss:", fn | |
fh = open(fn, 'w') | |
rheaders = {} | |
for i, j in environ.iteritems(): | |
if i.startswith("HTTP_"): | |
rheaders[i[5:].lower().replace('_', '-')] = j | |
conn = httplib.HTTPConnection(environ['PATH_INFO'][7:].split('/', 1)[0] + ':80') | |
conn.request(environ['REQUEST_METHOD'], '/' + environ['PATH_INFO'][7:].split('/', 1)[1], None, rheaders) | |
response = conn.getresponse() | |
status = "%s %s" % (response.status, response.reason) | |
headers = [(i, j) for i, j in response.getheaders() if i not in ('connection', 'keep-alive', 'transfer-encoding')] | |
body = [response.read()] | |
fh.write("%s\n" % (status, )) | |
fh.write("%s\n\n" % ("\n".join([":".join((i, j)) for i, j in headers]))) | |
fh.write(body[0]) | |
fh.close() | |
start_response(status, headers) | |
return body | |
httpd = make_server('', 8888, proxy) | |
print "Serving on port 127.0.0.1:8888..." | |
# Serve until process is killed | |
httpd.serve_forever() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment