-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What version of Go are you using (go version)?
go version go1.7.1 darwin/amd64
What operating system and processor architecture are you using (go env)?
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/user/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.7.1/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.7.1/libexec/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/jv/fp0q8rhx427f6p892mh4mpx40000gn/T/go-build154120093=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
What did you do?
Created a simple file server using http.FileServer to serve a directory containing a file with a colon (":") in the name.
package main
import "net/http"
func main() {
http.Handle("/", http.FileServer(http.Dir("files")))
http.ListenAndServe("127.0.0.1:8000", nil)
}# ls -1 files
normal_file
weird:file
What did you expect to see?
On browsing to 127.0.0.1:8000 I expected a list of the two files shown above and that I would be able to retrieve their contents by clicking their respective links.
What did you see instead?
I was able to retrieve normal_file, but selecting weird:file appeared to do nothing. Viewing the source, it became apparent that the browser was interpreting weird: as the scheme.
<pre>
<a href="normal_file">normal_file</a>
<a href="weird:file">weird:file</a>
</pre>A path segment that contains a colon character (e.g., "this:that")
cannot be used as the first segment of a relative-path reference, as
it would be mistaken for a scheme name. Such a segment must be
preceded by a dot-segment (e.g., "./this:that") to make a relative-
path reference.
I think the correct place to resolve the behavior is in URL.String(). It's comment states String reassembles the URL into a valid URL string., which is not accurate in this case of only a relative path with a colon in the first segment.
I'd be happy to contribute a fix. I believe adding the below before writing the path would correct the behavior for the specific case, without affecting the output otherwise.
if buf.Len() == 0 {
cIdx, sIdx := strings.IndexByte(path, ':'), strings.IndexByte(path, '/')
if cIdx > -1 && (sIdx < 0 || cIdx < sIdx) {
buf.WriteString("./")
}
}This produces:
<pre>
<a href="normal_file">normal_file</a>
<a href="./weird:file">weird:file</a>
</pre>