Fix prefix URL routing for encoded CIDR notation

Change route from wildcard /prefix/* to explicit /prefix/{prefix}/{len}
to properly handle URL-encoded IPv6 addresses with CIDR notation.

- Separate prefix and length into individual path parameters
- Add prefixURL template function for generating correct links
- Remove url.QueryUnescape from handlers (chi handles decoding)
This commit is contained in:
2026-01-01 05:37:12 +07:00
parent 27909e021f
commit 45810e3fc8
5 changed files with 40 additions and 30 deletions

View File

@@ -7,7 +7,6 @@ import (
"errors"
"net"
"net/http"
"net/url"
"runtime"
"sort"
"strconv"
@@ -736,21 +735,18 @@ func (s *Server) handleASDetailJSON() http.HandlerFunc {
// handlePrefixDetailJSON returns prefix details as JSON
func (s *Server) handlePrefixDetailJSON() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Get wildcard parameter (everything after /prefix/)
prefixParam := chi.URLParam(r, "*")
if prefixParam == "" {
writeJSONError(w, http.StatusBadRequest, "Prefix parameter is required")
// Get prefix and length from URL params
prefixParam := chi.URLParam(r, "prefix")
lenParam := chi.URLParam(r, "len")
if prefixParam == "" || lenParam == "" {
writeJSONError(w, http.StatusBadRequest, "Prefix and length parameters are required")
return
}
// URL decode the prefix parameter
prefix, err := url.QueryUnescape(prefixParam)
if err != nil {
writeJSONError(w, http.StatusBadRequest, "Invalid prefix parameter")
return
}
// Combine prefix and length into CIDR notation
prefix := prefixParam + "/" + lenParam
routes, err := s.db.GetPrefixDetailsContext(r.Context(), prefix)
if err != nil {
@@ -903,21 +899,18 @@ func (s *Server) handleASDetail() http.HandlerFunc {
// handlePrefixDetail returns a handler that serves the prefix detail HTML page
func (s *Server) handlePrefixDetail() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Get wildcard parameter (everything after /prefix/)
prefixParam := chi.URLParam(r, "*")
if prefixParam == "" {
http.Error(w, "Prefix parameter is required", http.StatusBadRequest)
// Get prefix and length from URL params
prefixParam := chi.URLParam(r, "prefix")
lenParam := chi.URLParam(r, "len")
if prefixParam == "" || lenParam == "" {
http.Error(w, "Prefix and length parameters are required", http.StatusBadRequest)
return
}
// URL decode the prefix parameter
prefix, err := url.QueryUnescape(prefixParam)
if err != nil {
http.Error(w, "Invalid prefix parameter", http.StatusBadRequest)
return
}
// Combine prefix and length into CIDR notation
prefix := prefixParam + "/" + lenParam
routes, err := s.db.GetPrefixDetailsContext(r.Context(), prefix)
if err != nil {

View File

@@ -28,7 +28,7 @@ func (s *Server) setupRoutes() {
// AS and prefix detail pages
r.Get("/as/{asn}", s.handleASDetail())
r.Get("/prefix/*", s.handlePrefixDetail())
r.Get("/prefix/{prefix}/{len}", s.handlePrefixDetail())
r.Get("/prefixlength/{length}", s.handlePrefixLength())
r.Get("/prefixlength6/{length}", s.handlePrefixLength6())
@@ -45,7 +45,7 @@ func (s *Server) setupRoutes() {
r.Get("/stats", s.handleStats())
r.Get("/ip/{ip}", s.handleIPLookup())
r.Get("/as/{asn}", s.handleASDetailJSON())
r.Get("/prefix/*", s.handlePrefixDetailJSON())
r.Get("/prefix/{prefix}/{len}", s.handlePrefixDetailJSON())
})
s.router = r