74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Serve a Vite SPA + proxy /pb to PocketBase. Generic, reusable."""
|
|
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
|
import urllib.request
|
|
import os
|
|
|
|
DIST = os.environ.get('SPQ_DIST', './dist')
|
|
PB = os.environ.get('PB_URL', 'http://127.0.0.1:8091')
|
|
|
|
class Handler(SimpleHTTPRequestHandler):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, directory=DIST, **kwargs)
|
|
|
|
def end_headers(self):
|
|
self.send_header('Access-Control-Allow-Origin', '*')
|
|
self.send_header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
|
|
self.send_header('Access-Control-Allow-Headers', 'Authorization, Content-Type')
|
|
super().end_headers()
|
|
|
|
def do_OPTIONS(self):
|
|
self.send_response(204)
|
|
self.end_headers()
|
|
|
|
def do_GET(self):
|
|
if self.path.startswith('/pb') or self.path.startswith('/api'):
|
|
self.proxy()
|
|
else:
|
|
full = os.path.join(DIST, self.path.lstrip('/'))
|
|
if not os.path.exists(full) or (os.path.isdir(full) and self.path != '/'):
|
|
self.path = '/index.html'
|
|
super().do_GET()
|
|
|
|
def do_POST(self):
|
|
if self.path.startswith('/pb') or self.path.startswith('/api'):
|
|
self.proxy()
|
|
else:
|
|
self.send_error(405)
|
|
|
|
def do_PUT(self): self.proxy()
|
|
def do_PATCH(self): self.proxy()
|
|
def do_DELETE(self): self.proxy()
|
|
|
|
def proxy(self):
|
|
# PB SDK calls /pb/api/collections/... — path already includes /api/
|
|
url = PB + self.path
|
|
if self.path.startswith('/pb'):
|
|
url = PB + self.path[3:] # strip /pb prefix
|
|
if not url.startswith(PB + '/api'):
|
|
url = PB + '/api' + self.path[3:]
|
|
body = None
|
|
if self.headers.get('Content-Length'):
|
|
body = self.rfile.read(int(self.headers['Content-Length']))
|
|
req = urllib.request.Request(url, data=body, method=self.command)
|
|
for k, v in self.headers.items():
|
|
if k.lower() not in ('host', 'connection', 'origin', 'referer'):
|
|
req.add_header(k, v)
|
|
try:
|
|
resp = urllib.request.urlopen(req)
|
|
self.send_response(resp.status)
|
|
for k, v in resp.headers.items():
|
|
if k.lower() not in ('transfer-encoding', 'connection'):
|
|
self.send_header(k, v)
|
|
self.end_headers()
|
|
self.wfile.write(resp.read())
|
|
except urllib.error.HTTPError as e:
|
|
self.send_response(e.code)
|
|
self.end_headers()
|
|
self.wfile.write(e.read())
|
|
|
|
if __name__ == '__main__':
|
|
server = HTTPServer(('0.0.0.0', 4173), Handler)
|
|
print(f'Serving {DIST} on 0.0.0.0:4173 (PB → {PB})')
|
|
server.serve_forever()
|