Skip to content

fix: strip query string before routing so bookmarkable URLs do not 404 - #81

Merged
phuryn merged 1 commit into
phuryn:mainfrom
jakduch:fix/route-strip-query-string
May 28, 2026
Merged

fix: strip query string before routing so bookmarkable URLs do not 404#81
phuryn merged 1 commit into
phuryn:mainfrom
jakduch:fix/route-strip-query-string

Conversation

@jakduch

@jakduch jakduch commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Closes #80

What

  • do_GET / do_POST route on urlparse(self.path).path instead of the raw self.path. URLs like /?range=all and /?range=30d&models=... now hit the index handler instead of falling through to 404.
  • Adds urlparse import (stdlib).
  • Two regression tests in tests/test_dashboard.py cover both /?range=... and /api/data?_=cachebust.
-from http.server import HTTPServer, BaseHTTPRequestHandler
+from http.server import HTTPServer, BaseHTTPRequestHandler
+from urllib.parse import urlparse

     def do_GET(self):
-        if self.path in ("/", "/index.html"):
+        path = urlparse(self.path).path
+        if path in ("/", "/index.html"):
             ...
-        elif self.path == "/api/data":
+        elif path == "/api/data":

Why

#80 has the full motivation. Short version: the dashboard rewrites the URL with ?range= via history.replaceState, so the first range-button click and any subsequent reload would break.

Verification

$ curl -o /dev/null -w "%%{http_code}\n" "http://127.0.0.1:8080/?range=all"
# before: 404
# after:  200

python -m unittest tests.test_dashboard -v — all 25 tests pass, including the two new ones.

do_GET and do_POST compared self.path literally, so any URL with query
parameters fell through to 404. The dashboard rewrites its own URL with
?range=... via history.replaceState, so the moment a user clicks a range
button, reloading or sharing the URL breaks.

Use urlparse() (already in stdlib) to route on the bare path. self.path
is otherwise unused — all client filtering is from /api/data.

Adds two regression tests covering /?range=... and /api/data?_=...

Closes phuryn#80
@josepe98

Copy link
Copy Markdown

Merged into our actively maintained fork at https://github.com/josepe98/claude-usage — thanks for this.

phuryn added a commit that referenced this pull request May 28, 2026
fix: use ThreadingHTTPServer so slow /api/data does not block other requests

HTTPServer serializes requests, so a slow /api/data response blocks the
browser from loading static assets or triggering /api/rescan. Pure stdlib
swap to ThreadingHTTPServer.

Resolved trivial import-line conflict against #81.
@phuryn

phuryn commented May 28, 2026

Copy link
Copy Markdown
Owner

[Claude & Codex] Merged into the DEV branch for v1.1.0 — your commit 0154b4d is preserved with your authorship. Especially appreciate the two regression tests; they nail down /?range=... and /api/data?_=cachebust.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bookmarkable URLs (?range=all) return 404 because handler compares self.path literally

3 participants