43 lines
1.7 KiB
Python
43 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Ollama shim for nightmare — binds 100.103.34.0:11440 (tailnet only), proxies /api/generate
|
|
to localhost:11434 and returns ONE plain, non-chunked response. Binds tailnet IP only so no
|
|
new exposure beyond the tailnet."""
|
|
import json
|
|
import http.server, socketserver, urllib.request
|
|
|
|
LOCAL = "http://127.0.0.1:11434"
|
|
BIND = ("100.103.34.0", 11440)
|
|
|
|
class H(http.server.BaseHTTPRequestHandler):
|
|
protocol_version = "HTTP/1.0" # no keep-alive, no chunked
|
|
def do_GET(self):
|
|
if self.path == "/api/tags":
|
|
body = urllib.request.urlopen(LOCAL + "/api/tags", timeout=10).read()
|
|
self.send_response(200); self.send_header("Content-Length", str(len(body)))
|
|
self.end_headers(); self.wfile.write(body)
|
|
else:
|
|
self.send_response(404); self.end_headers()
|
|
def do_POST(self):
|
|
n = int(self.headers.get("Content-Length", 0))
|
|
payload = json.loads(self.rfile.read(n) or b"{}")
|
|
payload["stream"] = False
|
|
req = urllib.request.Request(LOCAL + "/api/generate",
|
|
data=json.dumps(payload).encode(),
|
|
headers={"Content-Type": "application/json"})
|
|
with urllib.request.urlopen(req, timeout=600) as r:
|
|
body = r.read()
|
|
self.send_response(200)
|
|
self.send_header("Content-Type", "application/json")
|
|
self.send_header("Content-Length", str(len(body)))
|
|
self.end_headers()
|
|
self.wfile.write(body)
|
|
def log_message(self, *a):
|
|
pass
|
|
|
|
class TS(socketserver.ThreadingTCPServer):
|
|
allow_reuse_address = True
|
|
daemon_threads = True
|
|
|
|
if __name__ == "__main__":
|
|
TS(BIND, H).serve_forever()
|