aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-09-27 18:27:02 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2016-09-27 22:06:32 +0000
commita73020f847b3cf8575250569ebefb02573d19224 (patch)
treebfa9a6cac9ce924188221904712294b4eeea1fbf /src
parent36c164ec9c8597ec3507bb4aa9390603e9d29f7a (diff)
downloadgo-a73020f847b3cf8575250569ebefb02573d19224.tar.xz
net/http: add more IDNA2008 tests and fix some omissions
It wasn't lowercasing the string, folding widths, and putting strings into NFC form. Do those. Fixes #13835 Change-Id: Ia3de6159417cacec203b48e206e51d79f945df58 Reviewed-on: https://go-review.googlesource.com/29860 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/go/build/deps_test.go2
-rw-r--r--src/net/http/http.go10
-rw-r--r--src/net/http/http_test.go10
-rw-r--r--src/net/http/request.go19
-rw-r--r--src/net/http/transport.go3
5 files changed, 39 insertions, 5 deletions
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index c7e11498dd..fb31ac31c3 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -382,6 +382,8 @@ var pkgDeps = map[string][]string{
"golang_org/x/net/http2/hpack",
"golang_org/x/net/idna",
"golang_org/x/net/lex/httplex",
+ "golang_org/x/text/unicode/norm",
+ "golang_org/x/text/width",
"internal/nettrace",
"net/http/httptrace",
},
diff --git a/src/net/http/http.go b/src/net/http/http.go
index b34ae41ec5..258efbb152 100644
--- a/src/net/http/http.go
+++ b/src/net/http/http.go
@@ -6,6 +6,7 @@ package http
import (
"strings"
+ "unicode/utf8"
"golang_org/x/net/lex/httplex"
)
@@ -41,3 +42,12 @@ func removeEmptyPort(host string) string {
func isNotToken(r rune) bool {
return !httplex.IsTokenRune(r)
}
+
+func isASCII(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] >= utf8.RuneSelf {
+ return false
+ }
+ }
+ return true
+}
diff --git a/src/net/http/http_test.go b/src/net/http/http_test.go
index b95dab053c..c6c38ffcae 100644
--- a/src/net/http/http_test.go
+++ b/src/net/http/http_test.go
@@ -51,10 +51,18 @@ func TestCleanHost(t *testing.T) {
{"www.google.com foo", "www.google.com"},
{"www.google.com/foo", "www.google.com"},
{" first character is a space", ""},
+ {"[1::6]:8080", "[1::6]:8080"},
+
+ // Punycode:
{"гофер.рф/foo", "xn--c1ae0ajs.xn--p1ai"},
{"bücher.de", "xn--bcher-kva.de"},
{"bücher.de:8080", "xn--bcher-kva.de:8080"},
- {"[1::6]:8080", "[1::6]:8080"},
+ // Verify we convert to lowercase before punycode:
+ {"BÜCHER.de", "xn--bcher-kva.de"},
+ {"BÜCHER.de:8080", "xn--bcher-kva.de:8080"},
+ // Verify we normalize to NFC before punycode:
+ {"gophér.nfc", "xn--gophr-esa.nfc"}, // NFC input; no work needed
+ {"goph\u0065\u0301r.nfd", "xn--gophr-esa.nfd"}, // NFD input
}
for _, tt := range tests {
got := cleanHost(tt.in)
diff --git a/src/net/http/request.go b/src/net/http/request.go
index bebf55ccc4..a27d13cb98 100644
--- a/src/net/http/request.go
+++ b/src/net/http/request.go
@@ -27,6 +27,8 @@ import (
"sync"
"golang_org/x/net/idna"
+ "golang_org/x/text/unicode/norm"
+ "golang_org/x/text/width"
)
const (
@@ -581,6 +583,19 @@ func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, wai
return nil
}
+func idnaASCII(v string) (string, error) {
+ if isASCII(v) {
+ return v, nil
+ }
+ // The idna package doesn't do everything from
+ // https://tools.ietf.org/html/rfc5895 so we do it here.
+ // TODO(bradfitz): should the idna package do this instead?
+ v = strings.ToLower(v)
+ v = width.Fold.String(v)
+ v = norm.NFC.String(v)
+ return idna.ToASCII(v)
+}
+
// cleanHost cleans up the host sent in request's Host header.
//
// It both strips anything after '/' or ' ', and puts the value
@@ -600,13 +615,13 @@ func cleanHost(in string) string {
}
host, port, err := net.SplitHostPort(in)
if err != nil { // input was just a host
- a, err := idna.ToASCII(in)
+ a, err := idnaASCII(in)
if err != nil {
return in // garbage in, garbage out
}
return a
}
- a, err := idna.ToASCII(host)
+ a, err := idnaASCII(host)
if err != nil {
return in // garbage in, garbage out
}
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index cde7acac31..ed2b3a26ed 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -27,7 +27,6 @@ import (
"sync"
"time"
- "golang_org/x/net/idna"
"golang_org/x/net/lex/httplex"
)
@@ -1945,7 +1944,7 @@ var portMap = map[string]string{
// canonicalAddr returns url.Host but always with a ":port" suffix
func canonicalAddr(url *url.URL) string {
addr := url.Hostname()
- if v, err := idna.ToASCII(addr); err == nil {
+ if v, err := idnaASCII(addr); err == nil {
addr = v
}
port := url.Port()