-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Description
What version of Go are you using (go version)?
$ go version go version devel go1.17-6c1c055d1e Wed May 19 16:03:23 2021 -0700 linux/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/timothy-gu/.cache/go-build" GOENV="/home/timothy-gu/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/timothy-gu/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/timothy-gu/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/home/timothy-gu/dev/go/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/home/timothy-gu/dev/go/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="devel go1.17-a3a75c15dd Wed May 19 16:03:23 2021 -0700" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/home/timothy-gu/dev/go/go/src/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1447504073=/tmp/go-build -gno-record-gcc-switches"
What did you do?
https://play.golang.org/p/eDpmB6DyF_f
What did you expect to see?
I expected the following URL to be parsed:
&url.URL{Path: "/threeslashes"}This is since the first two slashes in ///threeslashes should start the host, while only the last slash belongs to the path.
What did you see instead?
&url.URL{Path: "///threeslashes"}There's actually a test case for this in net/url already:
Lines 212 to 223 in 6c1c055
| // Three leading slashes isn't an authority, but doesn't return an error. | |
| // (We can't return an error, as this code is also used via | |
| // ServeHTTP -> ReadRequest -> Parse, which is arguably a | |
| // different URL parsing context, but currently shares the | |
| // same codepath) | |
| { | |
| "///threeslashes", | |
| &URL{ | |
| Path: "///threeslashes", | |
| }, | |
| "", | |
| }, |
-
The comment says that "Three leading slashes isn't an authority." But it is. RFC 3986 gives the following definition:
relative-ref = relative-part [ "?" query ] [ "#" fragment ] relative-part = "//" authority path-abempty authority = [ userinfo "@" ] host [ ":" port ] host = IP-literal / IPv4address / reg-name reg-name = *( unreserved / pct-encoded / sub-delims ) path-abempty = *( "/" segment ) ; begins with "/" or is emptyWe see that
authoritycan absolutely be the empty string. In fact, url.Parse no longer returns an error if the Host is empty, so the comment is moot. -
The comment also says that ReadRequest depends on the url.Parse code path. However, this is not correct: it now uses url.ParseRequestURI, which does correctly parse the original URL as
Path: "///threeslashes".