From e476230f0ee46e496da0e23f8352a464530fd6ad Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sat, 4 Mar 2017 15:30:23 +0100 Subject: arch-proxy.py: support readonly cache --- arch-proxy.py | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/arch-proxy.py b/arch-proxy.py index e412364..d40cb4c 100755 --- a/arch-proxy.py +++ b/arch-proxy.py @@ -7,6 +7,7 @@ # ".download" extension. If the file exists and the file is not being # downloaded, resume the download (Range requests). +import argparse import http.server import os import socket @@ -15,9 +16,6 @@ import requests from contextlib import closing, contextmanager import fcntl -addr = ('', 8001) -cache_dir = os.getcwd() - DATE_FORMAT = '%a, %d %b %Y %H:%M:%S GMT' def text_to_epoch(text): return datetime.strptime(text, DATE_FORMAT).timestamp() @@ -58,6 +56,9 @@ class RequestHandler(http.server.BaseHTTPRequestHandler): @contextmanager def open_write_cache(self, path): + if self.server.is_readonly: + yield None + return temp_path = path + ".download" try: with open(temp_path, 'wb') as f: @@ -106,17 +107,19 @@ class RequestHandler(http.server.BaseHTTPRequestHandler): if head_only: list(remote_data) # consume yield and StopIteration if not head_only and remote_data: + cache_ok = False with self.open_write_cache(path) as cache_file: - if cache_file: + cache_ok = cache_file is not None + if cache_ok: for chunk in remote_data: cache_file.write(chunk) yield chunk - else: - # Cache file unavailable, just pass all data - yield from remote_data - return - # Write was successful, now fix mtime and rename - self.finish_cache(mtime_pointer[0]) + if cache_ok: + # Write was successful, now fix mtime and rename + self.finish_cache(mtime_pointer[0]) + else: + # Cache file unavailable, just pass all data + yield from remote_data def do_GET(self): try: @@ -143,19 +146,28 @@ class RequestHandler(http.server.BaseHTTPRequestHandler): def get_local_path(self): filename = os.path.basename(self.path) - return os.path.join(cache_dir, filename) + return os.path.join(self.server.cachedir, filename) def is_cacheable(self): """Whether the requested file should be cached.""" return self.path.endswith(".pkg.tar.xz") class SomeServer(http.server.HTTPServer): - def __init__(self, addr, handler): + def __init__(self, addr, handler, args): self.allow_reuse_address = True if ':' in addr[0]: self.address_family = socket.AF_INET6 super().__init__(addr, handler) + self.cachedir = args.cachedir + self.is_readonly = args.readonly + +parser = argparse.ArgumentParser() +parser.add_argument("--readonly", action="store_true") +parser.add_argument("--cachedir", default=os.getcwd()) +parser.add_argument("--port", type=int, default=8001) if __name__ == '__main__': - server = SomeServer(addr, RequestHandler) + args = parser.parse_args() + addr = ('', args.port) + server = SomeServer(addr, RequestHandler, args) server.serve_forever() -- cgit v1.2.1