Skip to content

Commit

Permalink
net/url: improve url parsing error messages by quoting
Browse files Browse the repository at this point in the history
Current implementation doesn't always make it obvious what the exact
problem with the URL is, so this makes it clearer by consistently quoting
the invalid URL, as is the norm in other parsing implementations, eg.:
strconv.Atoi(" 123") returns an error: parsing " 123": invalid syntax

Updates #29261

Change-Id: Icc6bff8b4a4584677c0f769992823e6e1e0d397d
GitHub-Last-Rev: 648b9d9
GitHub-Pull-Request: #29384
Reviewed-on: https://go-review.googlesource.com/c/go/+/185117
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
  • Loading branch information
stefanb authored and mvdan committed Aug 28, 2019
1 parent 5fb74fc commit 64cfe9f
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 11 deletions.
16 changes: 8 additions & 8 deletions src/net/http/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,27 +221,27 @@ func TestClientRedirects(t *testing.T) {

c := ts.Client()
_, err := c.Get(ts.URL)
if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
if e, g := `Get "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g {
t.Errorf("with default client Get, expected error %q, got %q", e, g)
}

// HEAD request should also have the ability to follow redirects.
_, err = c.Head(ts.URL)
if e, g := "Head /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
if e, g := `Head "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g {
t.Errorf("with default client Head, expected error %q, got %q", e, g)
}

// Do should also follow redirects.
greq, _ := NewRequest("GET", ts.URL, nil)
_, err = c.Do(greq)
if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
if e, g := `Get "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g {
t.Errorf("with default client Do, expected error %q, got %q", e, g)
}

// Requests with an empty Method should also redirect (Issue 12705)
greq.Method = ""
_, err = c.Do(greq)
if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
if e, g := `Get "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g {
t.Errorf("with default client Do and empty Method, expected error %q, got %q", e, g)
}

Expand Down Expand Up @@ -1172,22 +1172,22 @@ func TestStripPasswordFromError(t *testing.T) {
{
desc: "Strip password from error message",
in: "http://user:password@dummy.faketld/",
out: "Get http://user:***@dummy.faketld/: dummy impl",
out: `Get "http://user:***@dummy.faketld/": dummy impl`,
},
{
desc: "Don't Strip password from domain name",
in: "http://user:password@password.faketld/",
out: "Get http://user:***@password.faketld/: dummy impl",
out: `Get "http://user:***@password.faketld/": dummy impl`,
},
{
desc: "Don't Strip password from path",
in: "http://user:password@dummy.faketld/password",
out: "Get http://user:***@dummy.faketld/password: dummy impl",
out: `Get "http://user:***@dummy.faketld/password": dummy impl`,
},
{
desc: "Strip escaped password",
in: "http://user:pa%2Fssword@dummy.faketld/",
out: "Get http://user:***@dummy.faketld/: dummy impl",
out: `Get "http://user:***@dummy.faketld/": dummy impl`,
},
}
for _, tC := range testCases {
Expand Down
4 changes: 2 additions & 2 deletions src/net/http/readrequest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ var reqTests = []reqTest{
nil,
noBodyStr,
noTrailer,
"parse ../../../../etc/passwd: invalid URI for request",
`parse "../../../../etc/passwd": invalid URI for request`,
},

// Tests missing URL:
Expand All @@ -143,7 +143,7 @@ var reqTests = []reqTest{
nil,
noBodyStr,
noTrailer,
"parse : empty url",
`parse "": empty url`,
},

// Tests chunked body with trailer:
Expand Down
2 changes: 1 addition & 1 deletion src/net/url/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Error struct {
}

func (e *Error) Unwrap() error { return e.Err }
func (e *Error) Error() string { return e.Op + " " + e.URL + ": " + e.Err.Error() }
func (e *Error) Error() string { return fmt.Sprintf("%s %q: %s", e.Op, e.URL, e.Err) }

func (e *Error) Timeout() bool {
t, ok := e.Err.(interface {
Expand Down
6 changes: 6 additions & 0 deletions src/net/url/url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ var parseRequestURLTests = []struct {

{"foo.html", false},
{"../dir/", false},
{" http://foo.com", false},
{"http://192.168.0.%31/", false},
{"http://192.168.0.%31:8080/", false},
{"http://[fe80::%31]/", false},
Expand Down Expand Up @@ -1440,6 +1441,11 @@ func TestParseErrors(t *testing.T) {
{"mysql://x@y(z:123)/foo", true}, // not well-formed per RFC 3986, golang.org/issue/33646
{"mysql://x@y(1.2.3.4:123)/foo", true},

{" http://foo.com", true}, // invalid character in schema
{"ht tp://foo.com", true}, // invalid character in schema
{"ahttp://foo.com", false}, // valid schema characters
{"1http://foo.com", true}, // invalid character in schema

{"http://[]%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a/", true}, // golang.org/issue/11208
{"http://a b.com/", true}, // no space in host name please
{"cache_object://foo", true}, // scheme cannot have _, relative path cannot have : in first segment
Expand Down

0 comments on commit 64cfe9f

Please sign in to comment.