-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.
Milestone
Description
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (go version
)?
go version go1.10 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env
)?
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
What did you do?
The http.StripPrefix
handler doesnt preserve the original path of the request. Specifically, it completely unescapes it, replacing %2F
with /
, for example.
It also causes url.Path, url.RawPath, and url.EncodedPath() to become inconsistent with each other.
You can reproduce with the following program:
package main
import (
"fmt"
"net/http"
)
type exampleHandler struct {}
func (h *exampleHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "url.Path: %v\n", req.URL.Path)
fmt.Fprintf(w, "url.RawPath: %v\n", req.URL.RawPath)
fmt.Fprintf(w, "url.EscapedPath(): %v\n", req.URL.EscapedPath())
}
func main() {
sp := http.StripPrefix("/foo/", &exampleHandler{})
// server on port 8888 uses StripPrefix
server := &http.Server{
Addr: ":8888",
Handler: sp,
}
go server.ListenAndServe()
// server on port 9999 does not use StripPrefix
server2 := &http.Server{
Addr: ":9999",
Handler: &exampleHandler{},
}
server2.ListenAndServe()
}
What did you expect to see?
I expected to see
curl 'http://localhost:8888/foo/%2Fgoogle.com'
url.Path: %2Fgoogle.com
url.RawPath: %2Fgoogle.com
url.EscapedPath(): %2Fgoogle.com
What did you see instead?
This is the actual output:
curl 'http://localhost:8888/foo/%2Fgoogle.com'
url.Path: /google.com
url.RawPath: /foo/%2Fgoogle.com
url.EscapedPath(): /google.com
So to reiterate, I think EscapePath() should return a version of the path with all the original escaping and I think RawPath should be insync with Path and EscapedPath()
For a comparison, this is what the endpoint that doesnt use StripPrefix outputs:
curl 'http://localhost:9999/foo/%2Fgoogle.com'
url.Path: /foo//google.com
url.RawPath: /foo/%2Fgoogle.com
url.EscapedPath(): /foo/%2Fgoogle.com
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.