Commit 5c3827cb authored by Russ Cox's avatar Russ Cox

http: correct escaping of different parts of URL

Fixes #1076.

R=adg
CC=golang-dev
https://golang.org/cl/2248045
parent 9ff4565e
......@@ -45,7 +45,7 @@ func send(req *Request) (resp *Response, err os.Error) {
if !hasPort(addr) {
addr += ":" + req.URL.Scheme
}
info := req.URL.Userinfo
info := req.URL.RawUserinfo
if len(info) > 0 {
enc := base64.URLEncoding
encoded := make([]byte, enc.EncodedLen(len(info)))
......
......@@ -40,8 +40,8 @@ var reqTests = []reqTest{
Raw: "http://www.techcrunch.com/",
Scheme: "http",
RawPath: "/",
Authority: "www.techcrunch.com",
Userinfo: "",
RawAuthority: "www.techcrunch.com",
RawUserinfo: "",
Host: "www.techcrunch.com",
Path: "/",
RawQuery: "",
......
......@@ -191,7 +191,7 @@ func (req *Request) Write(w io.Writer) os.Error {
uri := req.RawURL
if uri == "" {
uri = valueOrDefault(urlEscape(req.URL.Path, false, false), "/")
uri = valueOrDefault(urlEscape(req.URL.Path, encodePath), "/")
if req.URL.RawQuery != "" {
uri += "?" + req.URL.RawQuery
}
......
......@@ -24,8 +24,8 @@ var reqWriteTests = []reqWriteTest{
Raw: "http://www.techcrunch.com/",
Scheme: "http",
RawPath: "http://www.techcrunch.com/",
Authority: "www.techcrunch.com",
Userinfo: "",
RawAuthority: "www.techcrunch.com",
RawUserinfo: "",
Host: "www.techcrunch.com",
Path: "/",
RawQuery: "",
......
This diff is collapsed.
......@@ -29,7 +29,7 @@ var urltests = []URLTest{
&URL{
Raw: "http://www.google.com",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
},
"",
......@@ -40,7 +40,7 @@ var urltests = []URLTest{
&URL{
Raw: "http://www.google.com/",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/",
Path: "/",
......@@ -53,12 +53,12 @@ var urltests = []URLTest{
&URL{
Raw: "http://www.google.com/file%20one%26two",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/file%20one%26two",
Path: "/file one&two",
},
"http://www.google.com/file%20one%26two",
"http://www.google.com/file%20one&two",
},
// user
URLTest{
......@@ -66,8 +66,8 @@ var urltests = []URLTest{
&URL{
Raw: "ftp://webmaster@www.google.com/",
Scheme: "ftp",
Authority: "webmaster@www.google.com",
Userinfo: "webmaster",
RawAuthority: "webmaster@www.google.com",
RawUserinfo: "webmaster",
Host: "www.google.com",
RawPath: "/",
Path: "/",
......@@ -80,8 +80,8 @@ var urltests = []URLTest{
&URL{
Raw: "ftp://john%20doe@www.google.com/",
Scheme: "ftp",
Authority: "john doe@www.google.com",
Userinfo: "john doe",
RawAuthority: "john%20doe@www.google.com",
RawUserinfo: "john%20doe",
Host: "www.google.com",
RawPath: "/",
Path: "/",
......@@ -94,7 +94,7 @@ var urltests = []URLTest{
&URL{
Raw: "http://www.google.com/?q=go+language",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/?q=go+language",
Path: "/",
......@@ -108,7 +108,7 @@ var urltests = []URLTest{
&URL{
Raw: "http://www.google.com/?q=go%20language",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/?q=go%20language",
Path: "/",
......@@ -122,7 +122,7 @@ var urltests = []URLTest{
&URL{
Raw: "http://www.google.com/a%20b?q=c+d",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/a%20b?q=c+d",
Path: "/a b",
......@@ -130,7 +130,7 @@ var urltests = []URLTest{
},
"",
},
// path without /, so no query parsing
// path without leading /, so no query parsing
URLTest{
"http:www.google.com/?q=go+language",
&URL{
......@@ -138,8 +138,21 @@ var urltests = []URLTest{
Scheme: "http",
RawPath: "www.google.com/?q=go+language",
Path: "www.google.com/?q=go+language",
OpaquePath: true,
},
"http:www.google.com/?q=go+language",
},
// path without leading /, so no query parsing
URLTest{
"http:%2f%2fwww.google.com/?q=go+language",
&URL{
Raw: "http:%2f%2fwww.google.com/?q=go+language",
Scheme: "http",
RawPath: "%2f%2fwww.google.com/?q=go+language",
Path: "//www.google.com/?q=go+language",
OpaquePath: true,
},
"http:www.google.com/%3fq%3dgo%2blanguage",
"http:%2f/www.google.com/?q=go+language",
},
// non-authority
URLTest{
......@@ -160,6 +173,7 @@ var urltests = []URLTest{
Scheme: "mailto",
RawPath: "webmaster@golang.org",
Path: "webmaster@golang.org",
OpaquePath: true,
},
"",
},
......@@ -190,8 +204,8 @@ var urltests = []URLTest{
&URL{
Raw: "http://user:password@google.com",
Scheme: "http",
Authority: "user:password@google.com",
Userinfo: "user:password",
RawAuthority: "user:password@google.com",
RawUserinfo: "user:password",
Host: "google.com",
},
"http://user:******@google.com",
......@@ -201,8 +215,8 @@ var urltests = []URLTest{
&URL{
Raw: "http://user:longerpass@google.com",
Scheme: "http",
Authority: "user:longerpass@google.com",
Userinfo: "user:longerpass",
RawAuthority: "user:longerpass@google.com",
RawUserinfo: "user:longerpass",
Host: "google.com",
},
"http://user:******@google.com",
......@@ -215,7 +229,7 @@ var urlnofragtests = []URLTest{
&URL{
Raw: "http://www.google.com/?q=go+language#foo",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/?q=go+language#foo",
Path: "/",
......@@ -231,7 +245,7 @@ var urlfragtests = []URLTest{
&URL{
Raw: "http://www.google.com/?q=go+language#foo",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/?q=go+language#foo",
Path: "/",
......@@ -245,21 +259,21 @@ var urlfragtests = []URLTest{
&URL{
Raw: "http://www.google.com/?q=go+language#foo%26bar",
Scheme: "http",
Authority: "www.google.com",
RawAuthority: "www.google.com",
Host: "www.google.com",
RawPath: "/?q=go+language#foo%26bar",
Path: "/",
RawQuery: "q=go+language",
Fragment: "foo&bar",
},
"",
"http://www.google.com/?q=go+language#foo&bar",
},
}
// more useful string for debugging than fmt's struct printer
func ufmt(u *URL) string {
return fmt.Sprintf("%q, %q, %q, %q, %q, %q, %q, %q, %q",
u.Raw, u.Scheme, u.RawPath, u.Authority, u.Userinfo,
u.Raw, u.Scheme, u.RawPath, u.RawAuthority, u.RawUserinfo,
u.Host, u.Path, u.RawQuery, u.Fragment)
}
......@@ -307,11 +321,9 @@ func DoTestString(t *testing.T, parse func(string) (*URL, os.Error), name string
func TestURLString(t *testing.T) {
DoTestString(t, ParseURL, "ParseURL", urltests)
DoTestString(t, ParseURL, "ParseURL", urlfragtests)
DoTestString(t, ParseURL, "ParseURL", urlnofragtests)
DoTestString(t, ParseURLReference, "ParseURLReference", urltests)
DoTestString(t, ParseURLReference, "ParseURLReference", urlfragtests)
DoTestString(t, ParseURLReference, "ParseURLReference", urlnofragtests)
}
type URLEscapeTest struct {
......@@ -467,3 +479,31 @@ func TestCanonicalPath(t *testing.T) {
}
}
}
type UserinfoTest struct {
User string
Password string
Raw string
}
var userinfoTests = []UserinfoTest{
UserinfoTest{"user", "password", "user:password"},
UserinfoTest{"foo:bar", "~!@#$%^&*()_+{}|[]\\-=`:;'\"<>?,./",
"foo%3abar:~!%40%23$%25%5e&*()_+%7b%7d%7c%5b%5d%5c-=%60%3a;'%22%3c%3e?,.%2f"},
}
func TestEscapeUserinfo(t *testing.T) {
for _, tt := range userinfoTests {
if raw := EscapeUserinfo(tt.User, tt.Password); raw != tt.Raw {
t.Errorf("EscapeUserinfo(%q, %q) = %q, want %q", tt.User, tt.Password, raw, tt.Raw)
}
}
}
func TestUnescapeUserinfo(t *testing.T) {
for _, tt := range userinfoTests {
if user, pass, err := UnescapeUserinfo(tt.Raw); user != tt.User || pass != tt.Password || err != nil {
t.Errorf("UnescapeUserinfo(%q) = %q, %q, %v, want %q, %q, nil", tt.Raw, user, pass, err, tt.User, tt.Password)
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment