Last active
May 29, 2024 10:05
-
-
Save iTrooz/0192ab377b504dfb9a04f387cda91c84 to your computer and use it in GitHub Desktop.
varnish_httpcache
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 python3 | |
# Easier Frontend for varnishd | |
# Example: ./httpcache.py -u google.com | |
# Then, requests to localhost:8080 forwarded to google.com and cached | |
# Licence: MIT | |
import os | |
import tempfile | |
import subprocess | |
import shutil | |
import argparse | |
def parse_upstream(upstream: str) -> tuple[str, str]: | |
# handle protocol | |
defPort = "80" | |
if upstream.startswith("http://"): | |
upstream = upstream[7:] | |
defPort = "80" | |
elif upstream.startswith("https://"): | |
upstream = upstream[8:] | |
defPort = "443" | |
# handle port | |
port_index = upstream.find(":") | |
if port_index == -1: | |
return upstream, defPort | |
else: | |
return upstream[:port_index], upstream[port_index+1:] | |
# Parse command line arguments | |
parser = argparse.ArgumentParser(description='HTTP Cache with Varnish') | |
parser.add_argument('--upstream', '-u', type=str, required=True, help='Backend host') | |
parser.add_argument('--port', '-p', type=str, default='8080', help='Varnish port') | |
parser.add_argument('--verbose', '-v', action="count") | |
args = parser.parse_args() | |
# Configuration | |
upstream_host, upstream_port = parse_upstream(args.upstream) | |
# VCL template with placeholders | |
vcl_content = """ | |
vcl 4.0; | |
backend default { | |
.host = "{upstream_host}"; | |
.port = "{upstream_port}"; | |
.host_header = "{upstream_host}:{upstream_port}"; | |
} | |
sub vcl_backend_fetch { | |
unset bereq.http.host; | |
} | |
sub vcl_recv { | |
# Add custom logic here if needed | |
} | |
sub vcl_backend_response { | |
set beresp.ttl = 24h; # Set TTL for cached objects | |
} | |
sub vcl_deliver { | |
if (obj.hits > 0) { | |
set resp.http.X-Cache = "HIT"; | |
} else { | |
set resp.http.X-Cache = "MISS"; | |
} | |
} | |
""" | |
vcl_content = vcl_content.replace("{upstream_host}", upstream_host) | |
vcl_content = vcl_content.replace("{upstream_port}", upstream_port) | |
tmpdir = tempfile.TemporaryDirectory(delete=False).name | |
if args.verbose: | |
print("Varnish tmp folder:", tmpdir) | |
# Create a temporary VCL file | |
tmp_vcl_file = os.path.join(tmpdir, "file.vcl") | |
with open(tmp_vcl_file, "wb") as file: | |
file.write(vcl_content.encode('utf-8')) | |
try: | |
print(f"Varnish started on port {args.port} with backend {upstream_host}:{upstream_port}") | |
proc = subprocess.run([ | |
"varnishd", | |
"-F", | |
"-a", f":{args.port}", | |
"-f", tmp_vcl_file, | |
"-s", "malloc,256m", | |
"-n", os.path.join(tmpdir, "cache") | |
], check=False, capture_output=not args.verbose) | |
# Process has finished | |
if not args.verbose and proc.returncode != 0: | |
print("varnishd crashed. Logs:") | |
print("\nStdout:") | |
print(proc.stdout.decode('utf-8')) | |
print("\nStderr:") | |
print(proc.stderr.decode('utf-8')) | |
exit(1) | |
finally: | |
shutil.rmtree(tmpdir) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment