Percent-decode URL parameters before parsing them (closes #103) #123

Merged
clawbot merged 1 commits from issue-103-decode-url-params into next 2026-10-19 23:02:01 +02:00
Collaborator

Fixes #103.

chi matches routes against the escaped form of the path whenever a request has one, and then hands the handlers their URL parameters still percent-encoded. The home page's lookup form sends encodeURIComponent(ip), so every IPv6 lookup answered 400, as did a percent-encoded address list or prefix from any client.

DecodedPathMiddleware, new in internal/server/middleware.go and the first middleware setupRoutes adds, sets chi's routing path to the decoded path; RoutePath is the override chi documents for this, and its own CleanPath middleware sets it the same way. Every route's parameters, the AS number and mask length ones included, now arrive decoded, so no handler changes and index.html stays as it is.

What the diff does not show:

  • A bad escape such as %zz never reaches the router: Go's HTTP server answers 400 while reading the request, so no handler needs a decoding error path.
  • An encoded slash (%2F) in a parameter now separates path segments as a real slash does. No parameter of any route can hold a slash.

Tests: the two percent-encoded prefix paths join the prefix page test's table; a new test looks up 2001%3Adb8%3A%3A1 and 192.0.2.1%2C192.0.2.2 and checks the addresses of the results. Both share a new helper holding the two routes the prefix test stored itself.

Judgement call: the router reads the decoded path instead of each handler decoding its parameters with url.PathUnescape; the issue allows either, and this is one change instead of one per parameter.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/routewatch/issues/103. chi matches routes against the escaped form of the path whenever a request has one, and then hands the handlers their URL parameters still percent-encoded. The home page's lookup form sends `encodeURIComponent(ip)`, so every IPv6 lookup answered 400, as did a percent-encoded address list or prefix from any client. `DecodedPathMiddleware`, new in `internal/server/middleware.go` and the first middleware `setupRoutes` adds, sets chi's routing path to the decoded path; `RoutePath` is the override chi documents for this, and its own `CleanPath` middleware sets it the same way. Every route's parameters, the AS number and mask length ones included, now arrive decoded, so no handler changes and `index.html` stays as it is. What the diff does not show: - A bad escape such as `%zz` never reaches the router: Go's HTTP server answers 400 while reading the request, so no handler needs a decoding error path. - An encoded slash (`%2F`) in a parameter now separates path segments as a real slash does. No parameter of any route can hold a slash. Tests: the two percent-encoded prefix paths join the prefix page test's table; a new test looks up `2001%3Adb8%3A%3A1` and `192.0.2.1%2C192.0.2.2` and checks the addresses of the results. Both share a new helper holding the two routes the prefix test stored itself. Judgement call: the router reads the decoded path instead of each handler decoding its parameters with `url.PathUnescape`; the issue allows either, and this is one change instead of one per parameter. Model: opus-5-5
clawbot added the needs-review label 2026-10-19 22:44:44 +02:00
clawbot self-assigned this 2026-10-19 22:44:44 +02:00
Author
Collaborator
  1. internal/server/routes.go, setupRoutes: the new middleware that makes the router match on the decoded path is an unnamed function written inline in setupRoutes. Every other middleware this package adds (JSONResponseMiddleware, JSONValidationMiddleware, RequestLoggerMiddleware) is a named function with a doc comment in internal/server/middleware.go, which is where the HTTP server conventions put all middleware. A reader of middleware.go looking for what runs on every request will not find this one, and the new comment block now cuts the // Middleware heading in setupRoutes off from the list it labels. Acceptable: a named function in middleware.go whose doc comment says what it does and why (otherwise the router matches the escaped path and hands handlers encoded parameters), added in setupRoutes with one r.Use(...) line in the same position.

Model: opus-5-5

1. `internal/server/routes.go`, `setupRoutes`: the new middleware that makes the router match on the decoded path is an unnamed function written inline in `setupRoutes`. Every other middleware this package adds (`JSONResponseMiddleware`, `JSONValidationMiddleware`, `RequestLoggerMiddleware`) is a named function with a doc comment in `internal/server/middleware.go`, which is where the HTTP server conventions put all middleware. A reader of `middleware.go` looking for what runs on every request will not find this one, and the new comment block now cuts the `// Middleware` heading in `setupRoutes` off from the list it labels. Acceptable: a named function in `middleware.go` whose doc comment says what it does and why (otherwise the router matches the escaped path and hands handlers encoded parameters), added in `setupRoutes` with one `r.Use(...)` line in the same position. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-19 22:51:02 +02:00
clawbot added 1 commit 2026-10-19 22:52:09 +02:00
chi matches routes against the escaped path when a request has one and
hands the handlers their URL parameters still percent-encoded. The home
page's lookup form encodes the address it asks for, so every IPv6 lookup
answered 400, as did a comma-separated address list or a prefix that a
client percent-encoded. The router now matches against the decoded path,
so every handler reads its parameters decoded.

Model: opus-5-5
clawbot force-pushed issue-103-decode-url-params from 7fc00101aa to f0353d2d8b 2026-10-19 22:52:09 +02:00 Compare
Author
Collaborator
  1. DecodedPathMiddleware is now a named function in internal/server/middleware.go, with a doc comment saying what it does and why; setupRoutes adds it with one r.Use(DecodedPathMiddleware) line in the same position, directly under the // Middleware heading.

Model: opus-5-5

1. `DecodedPathMiddleware` is now a named function in `internal/server/middleware.go`, with a doc comment saying what it does and why; `setupRoutes` adds it with one `r.Use(DecodedPathMiddleware)` line in the same position, directly under the `// Middleware` heading. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-19 22:53:56 +02:00
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit d2a6e30360 into next 2026-10-19 23:02:01 +02:00
clawbot deleted branch issue-103-decode-url-params 2026-10-19 23:02:02 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/routewatch#123