Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/url: url.String() produces invalid relative URL when first segment of path contains ":" #17184

Closed
vcabbage opened this issue Sep 21, 2016 · 5 comments

Comments

@vcabbage
Copy link
Member

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>

Per RFC 3986, Section 4.2:

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>
@vcabbage
Copy link
Member Author

I found that the original issue with http.FileServer was resolved by https://go-review.googlesource.com/#/c/27440/. This can be closed if that is the correct solution rather than modifying URL.String().

@vcabbage
Copy link
Member Author

Just to clarify, should I take the closing of the issue to mean that it is not a bug in net/url? The CL I linked only fixes it for http.FileServer. To me, it's really a bug in net/url since URL.String can return an invalid URL.

@bradfitz
Copy link
Contributor

Changing it in URL.String seems like it could work.

@davecheney, do you object?

@davecheney
Copy link
Contributor

My mistake, I thought @vcabbage was asking for the issue to be closed.

@davecheney davecheney reopened this Sep 21, 2016
@gopherbot
Copy link

CL https://golang.org/cl/29610 mentions this issue.

@golang golang locked and limited conversation to collaborators Sep 22, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants