|
| 1 | +# Originally from http://sharebear.co.uk/blog/2009/09/17/very-simple-python-caching-proxy/ |
| 2 | +# |
| 3 | +# Usage: |
| 4 | +# A call to http://localhost:8000/example.com/foo.html will cache the file |
| 5 | +# at http://example.com/foo.html on disc and not redownload it again. |
| 6 | +# To clear the cache simply do a `rm *.cached`. To stop the server simply |
| 7 | +# send SIGINT (Ctrl-C). It does not handle any headers or post data. |
| 8 | +# |
| 9 | +# see also: https://pymotw.com/2/BaseHTTPServer/ |
| 10 | + |
| 11 | +import BaseHTTPServer |
| 12 | +# import hashlib |
| 13 | +import os |
| 14 | +import urllib2 |
| 15 | + |
| 16 | +from BaseHTTPServer import HTTPServer |
| 17 | +from SocketServer import ThreadingMixIn |
| 18 | +import tempfile |
| 19 | + |
| 20 | +class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): |
| 21 | + pass |
| 22 | + |
| 23 | +class CacheHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 24 | + def ok(self): |
| 25 | + self.send_response(200) |
| 26 | + self.send_header("Content-Encoding", "gzip") |
| 27 | + self.end_headers() |
| 28 | + |
| 29 | + def do_GET(self): |
| 30 | + |
| 31 | + dirname = ".tiles/" + os.path.dirname(self.path)[1:] |
| 32 | + filename = os.path.basename(self.path) |
| 33 | + |
| 34 | + while not os.path.exists(dirname): |
| 35 | + # might be a race here |
| 36 | + try: |
| 37 | + os.makedirs(dirname) |
| 38 | + except: |
| 39 | + None |
| 40 | + |
| 41 | + cache_filename = dirname + "/" + filename |
| 42 | + |
| 43 | + if os.path.exists(cache_filename): |
| 44 | + data = open(cache_filename, mode='rb').readlines() |
| 45 | + self.ok() |
| 46 | + self.wfile.writelines(data) |
| 47 | + return |
| 48 | + |
| 49 | + print "fetching: %s" % (cache_filename) |
| 50 | + data = urllib2.urlopen("http:/" + self.path, timeout=10).readlines() |
| 51 | + self.ok() |
| 52 | + self.wfile.writelines(data) |
| 53 | + |
| 54 | + f = tempfile.NamedTemporaryFile(dir=os.path.dirname(cache_filename), |
| 55 | + mode='wb', |
| 56 | + delete=False) |
| 57 | + f.writelines(data) |
| 58 | + f.close() |
| 59 | + os.rename(f.name, cache_filename) |
| 60 | + |
| 61 | +def run(): |
| 62 | + if not os.path.exists(".tiles"): |
| 63 | + os.makedirs(".tiles") |
| 64 | + |
| 65 | + server_address = ('', 8000) |
| 66 | + httpd = ThreadedHTTPServer(server_address, CacheHandler) |
| 67 | + httpd.serve_forever() |
| 68 | + |
| 69 | +if __name__ == '__main__': |
| 70 | + run() |
0 commit comments