Open Nyoroon opened 1 year ago
@Nyoroon the .
in regex means "any character", so if you want to match a literal .
, you need to escape it. Your string would then be: "/{param:\\.+}.json"
.
@Nyoroon the
.
in regex means "any character", so if you want to match a literal.
, you need to escape it. Your string would then be:"/{param:\\.+}.json"
.
Yeah, and I want to match "any character", but it matches "any character except dot". I have an example in post.
Okay, have you tried "/{param:[.\\.]+}.json"
?
@Nyoroon
This is not really a problem with the regex, it fails due to ambiguity.
If you were to modify the param to "/{param:.+}:json"
(note the colon, it can be anything else) then make the request /param.with.dots:json
, this will work because there is no ambiguity, chi knows everything before the colon (:
) is supposed to be the param.
I suggest you define a the route like this r.Get("/{param:.+\\.json}", ...)
, then strip out and process the param manually in your handler.
@Nyoroon I agree that the following code is clearly buggy, as the route matches /param.json
path but it doesn't match /param.tar.gz
.
r.Get("/{param:.+}.json", func(w http.ResponseWriter, r *http.Request) {
param := chi.URLParam(r, "param")
_, _ = fmt.Fprintf(w, "param=%s", param)
})
However, fixing this bug is a very delicate work (see https://github.com/go-chi/chi/pull/813#pullrequestreview-2328041891) and potentially a breaking change and I'm not sure if it's worth it.
But.. I think I found a workaround for your example. Hope it helps!
r.Get("/{param:[^.]+}.{ext:.+}", func(w http.ResponseWriter, r *http.Request) {
param := chi.URLParam(r, "param")
ext := chi.URLParam(r, "ext")
_, _ = fmt.Fprintf(w, "param=%s, ext=%s", param, ext)
})
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/go-chi/chi/v5"
)
func main() {
mux := chi.NewMux()
mux.Get("/{param:[^.]+}.{ext:.+}", func(w http.ResponseWriter, r *http.Request) {
param := chi.URLParam(r, "param")
ext := chi.URLParam(r, "ext")
_, _ = fmt.Fprintf(w, "param=%s, ext=%s", param, ext)
})
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/param.json", nil)
mux.ServeHTTP(rec, req)
fmt.Printf("code: %d, body: %s\n", rec.Code, rec.Body)
rec = httptest.NewRecorder()
req = httptest.NewRequest(http.MethodGet, "/param.tar.gz", nil)
mux.ServeHTTP(rec, req)
fmt.Printf("code: %d, body: %s\n", rec.Code, rec.Body)
rec = httptest.NewRecorder()
req = httptest.NewRequest(http.MethodGet, "/param.with.dots.json", nil)
mux.ServeHTTP(rec, req)
fmt.Printf("code: %d, body: %s\n", rec.Code, rec.Body)
}
$ go run ./
code: 200, body: param=param, ext=json
code: 200, body: param=param, ext=tar.gz
code: 200, body: param=param, ext=with.dots.json
Perhaps we could add this to the examples?
Example program:
Expected:
Got: