v1.1.0: fix /crawl/* GET routes (move handlers to do_GET start)
Bug: /crawl/status and /crawl/download handlers were placed after return statement in do_GET, making them dead code. Static file check would 404 + fall through to index.html (HTML 200), masking the real issue. Fix: move /crawl/* API handlers to top of do_GET, before static file check. Now /crawl/status returns JSON, /crawl/download returns file with proper Content-Disposition. Also: cleanup duplicate def do_GET introduced by earlier patch. Reported by: Hermes (@Ir_workbot)
This commit is contained in:
@@ -313,9 +313,52 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self.wfile.write(json.dumps(data).encode())
|
||||
|
||||
def do_GET(self):
|
||||
# Static file serving: <file> or /url2pdf-tools/<file> → /opt/url2pdf/<file>
|
||||
# (nginx strips /url2pdf prefix; we accept both with and without it)
|
||||
# Static file serving: <file> or /url2pdf-tools/<file> -> /opt/url2pdf/<file>
|
||||
# 1. /crawl/status?job=ID - poll job status
|
||||
if self.path.startswith("/crawl/status"):
|
||||
qs = urllib.parse.urlparse(self.path).query
|
||||
params = urllib.parse.parse_qs(qs)
|
||||
job = params.get("job", [None])[0]
|
||||
if not job:
|
||||
self._json(400, {"error": "Missing job"})
|
||||
return
|
||||
sp = os.path.join(JOBS_DIR, job, "status.json")
|
||||
if os.path.exists(sp):
|
||||
with open(sp) as f:
|
||||
self._json(200, json.load(f))
|
||||
else:
|
||||
self._json(200, {"status": "pending"})
|
||||
return
|
||||
|
||||
# 2. /crawl/download?job=ID&format=md|pdf - download output
|
||||
if self.path.startswith("/crawl/download"):
|
||||
qs = urllib.parse.urlparse(self.path).query
|
||||
params = urllib.parse.parse_qs(qs)
|
||||
job = params.get("job", [None])[0]
|
||||
fmt = params.get("format", ["pdf"])[0]
|
||||
if not job:
|
||||
self.send_error(400)
|
||||
return
|
||||
jdir = os.path.join(JOBS_DIR, job)
|
||||
if fmt == "md":
|
||||
fp = os.path.join(jdir, "output.md")
|
||||
ct = "text/markdown"
|
||||
else:
|
||||
fp = os.path.join(jdir, "output.pdf")
|
||||
ct = "application/pdf"
|
||||
if not os.path.exists(fp):
|
||||
self.send_error(404, "Not found")
|
||||
return
|
||||
with open(fp, "rb") as f:
|
||||
data = f.read()
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", ct)
|
||||
self.send_header("Content-Disposition", f'attachment; filename="{job}.{fmt}"')
|
||||
self.send_header("Content-Length", str(len(data)))
|
||||
self.end_headers()
|
||||
self.wfile.write(data)
|
||||
return
|
||||
|
||||
# 3. Static file serving: <file> or /url2pdf-tools/<file> -> /opt/url2pdf/<file>
|
||||
# (nginx strips /url2pdf prefix; we accept both with and without it)
|
||||
if self.path.startswith("/url2pdf-tools/"):
|
||||
rel = self.path[len("/url2pdf-tools/"):]
|
||||
@@ -332,7 +375,6 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self.send_error(400, "Bad path")
|
||||
return
|
||||
fp = os.path.join("/opt/url2pdf", safe)
|
||||
fp = os.path.join("/opt/url2pdf", safe)
|
||||
if os.path.isfile(fp):
|
||||
import mimetypes
|
||||
ct, _ = mimetypes.guess_type(fp)
|
||||
@@ -346,63 +388,10 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self.end_headers()
|
||||
self.wfile.write(data)
|
||||
return
|
||||
# file not found under /opt/url2pdf - fall through to API or HTML fallback
|
||||
# file not found under /opt/url2pdf
|
||||
self.send_error(404, "Not found: " + fp)
|
||||
return
|
||||
|
||||
if self.path.startswith("/crawl/status"):
|
||||
qs = urllib.parse.urlparse(self.path).query
|
||||
params = urllib.parse.parse_qs(qs)
|
||||
job = params.get("job", [None])[0]
|
||||
if not job:
|
||||
self._json(400, {"error": "Missing job"})
|
||||
return
|
||||
sp = os.path.join(JOBS_DIR, job, "status.json")
|
||||
if os.path.exists(sp):
|
||||
with open(sp) as f:
|
||||
self._json(200, json.load(f))
|
||||
else:
|
||||
self._json(200, {"status": "pending"})
|
||||
return
|
||||
|
||||
|
||||
if self.path.startswith("/crawl/download"):
|
||||
qs = urllib.parse.urlparse(self.path).query
|
||||
params = urllib.parse.parse_qs(qs)
|
||||
job = params.get("job", [None])[0]
|
||||
fmt = params.get("format", ["pdf"])[0]
|
||||
if not job:
|
||||
self.send_error(400)
|
||||
return
|
||||
|
||||
jdir = os.path.join(JOBS_DIR, job)
|
||||
if fmt == "md":
|
||||
fp = os.path.join(jdir, "output.md")
|
||||
ct = "text/markdown"
|
||||
else:
|
||||
fp = os.path.join(jdir, "output.pdf")
|
||||
ct = "application/pdf"
|
||||
|
||||
if not os.path.exists(fp):
|
||||
self.send_error(404, "Not found")
|
||||
return
|
||||
|
||||
with open(fp, "rb") as f:
|
||||
data = f.read()
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", ct)
|
||||
self.send_header("Content-Disposition", f'attachment; filename="{job}.{fmt}"')
|
||||
self.send_header("Content-Length", str(len(data)))
|
||||
self.end_headers()
|
||||
self.wfile.write(data)
|
||||
return
|
||||
|
||||
# Serve HTML
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "text/html")
|
||||
self.end_headers()
|
||||
self.wfile.write(HTML.encode())
|
||||
|
||||
def do_POST(self):
|
||||
length = int(self.headers.get("Content-Length", 0))
|
||||
body = self.rfile.read(length)
|
||||
|
||||
Reference in New Issue
Block a user