You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Router does parses %2F (URL-encoded /) as a regular / and uses that as a delimiter in the path.
Expected Behavior
I would expect the router to treat the URL-encoded %2F as an encoded value in the path that is not the same as /. See the test below. That should explain the expected behaviour the best.
Steps To Reproduce
package whatever
import (
"fmt""io""net/http""net/url""sync""testing""time""github.com/gorilla/mux"
)
funcTestRouter(t*testing.T) {
client:= http.Client{
Timeout: time.Second*3,
}
stringToBeEscaped:="123/ \\ :+ -;& ěščřžýáíé=§¨ů|"// you can try deleting the number and the tests fails because the expected strings do not matchpathEscaped:=url.PathEscape(stringToBeEscaped)
queryEscaped:=url.QueryEscape(stringToBeEscaped)
fmt.Println("Original string: ", stringToBeEscaped)
fmt.Println("Path escaped: ", pathEscaped)
fmt.Println("Query escaped: ", queryEscaped)
pathUnescaped, _:=url.PathUnescape(pathEscaped)
queryUnescaped, _:=url.QueryUnescape(queryEscaped)
fmt.Println("Path unescaped: ", pathUnescaped)
fmt.Println("Query unescaped: ", queryUnescaped)
fmt.Println("Path unescaped match: ", pathUnescaped==stringToBeEscaped)
fmt.Println("Query unescaped match: ", queryUnescaped==stringToBeEscaped)
serviceUrl:=fmt.Sprintf("http://localhost:8080/path/%s?foo=%s", pathEscaped, queryEscaped)
fmt.Println("Service URL: ", serviceUrl)
request, err:=http.NewRequest(http.MethodGet, serviceUrl, nil)
iferr!=nil {
t.Fatal(err)
}
router:=mux.NewRouter()
router.HandleFunc("/path/{positional_argument}", func(w http.ResponseWriter, r*http.Request) {
vars:=mux.Vars(r)
ifvars["positional_argument"] !=stringToBeEscaped {
t.Fatalf("expected positional argument to be `%s` but got `%s`", stringToBeEscaped, vars["positional_argument"])
}
queryParam:=r.URL.Query().Get("foo")
ifqueryParam!=stringToBeEscaped {
t.Fatalf("expected query parameter to be `%s` but got `%s`", stringToBeEscaped, queryParam)
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}).Methods(http.MethodGet)
wg:=&sync.WaitGroup{}
wg.Add(1)
gofunc() {
wg.Done()
iferr:=http.ListenAndServe(":8080", router); err!=nil {
t.Error(err)
}
}()
wg.Wait()
time.Sleep(time.Second)
response, err:=client.Do(request)
iferr!=nil {
t.Fatal(err)
}
deferresponse.Body.Close()
ifresponse.StatusCode!=http.StatusOK {
t.Fatalf("expected status code %d but got %d", http.StatusOK, response.StatusCode)
}
body, err:=io.ReadAll(response.Body)
iferr!=nil {
t.Fatal(err)
}
ifstring(body) !="OK" {
t.Fatalf("expected body to be `%s` but got `%s`", "OK", string(body))
}
}
Anything else?
No response
The text was updated successfully, but these errors were encountered:
domcermak
changed the title
[BUG] Router does now distinguish between / and %2F in the request path
[BUG] Router does not distinguish between / and %2F in the request path
Nov 11, 2023
Is there an existing issue for this?
Current Behavior
Router does parses
%2F
(URL-encoded/
) as a regular/
and uses that as a delimiter in the path.Expected Behavior
I would expect the router to treat the URL-encoded
%2F
as an encoded value in the path that is not the same as/
. See the test below. That should explain the expected behaviour the best.Steps To Reproduce
Anything else?
No response
The text was updated successfully, but these errors were encountered: