|  | // Copyright 2012 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | // Package idna implements IDNA2008 (Internationalized Domain Names for | 
|  | // Applications), defined in RFC 5890, RFC 5891, RFC 5892, RFC 5893 and | 
|  | // RFC 5894. | 
|  | package idna // import "golang.org/x/net/idna" | 
|  |  | 
|  | import ( | 
|  | "strings" | 
|  | "unicode/utf8" | 
|  | ) | 
|  |  | 
|  | // TODO(nigeltao): specify when errors occur. For example, is ToASCII(".") or | 
|  | // ToASCII("foo\x00") an error? See also http://www.unicode.org/faq/idn.html#11 | 
|  |  | 
|  | // acePrefix is the ASCII Compatible Encoding prefix. | 
|  | const acePrefix = "xn--" | 
|  |  | 
|  | // ToASCII converts a domain or domain label to its ASCII form. For example, | 
|  | // ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and | 
|  | // ToASCII("golang") is "golang". | 
|  | func ToASCII(s string) (string, error) { | 
|  | if ascii(s) { | 
|  | return s, nil | 
|  | } | 
|  | labels := strings.Split(s, ".") | 
|  | for i, label := range labels { | 
|  | if !ascii(label) { | 
|  | a, err := encode(acePrefix, label) | 
|  | if err != nil { | 
|  | return "", err | 
|  | } | 
|  | labels[i] = a | 
|  | } | 
|  | } | 
|  | return strings.Join(labels, "."), nil | 
|  | } | 
|  |  | 
|  | // ToUnicode converts a domain or domain label to its Unicode form. For example, | 
|  | // ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and | 
|  | // ToUnicode("golang") is "golang". | 
|  | func ToUnicode(s string) (string, error) { | 
|  | if !strings.Contains(s, acePrefix) { | 
|  | return s, nil | 
|  | } | 
|  | labels := strings.Split(s, ".") | 
|  | for i, label := range labels { | 
|  | if strings.HasPrefix(label, acePrefix) { | 
|  | u, err := decode(label[len(acePrefix):]) | 
|  | if err != nil { | 
|  | return "", err | 
|  | } | 
|  | labels[i] = u | 
|  | } | 
|  | } | 
|  | return strings.Join(labels, "."), nil | 
|  | } | 
|  |  | 
|  | func ascii(s string) bool { | 
|  | for i := 0; i < len(s); i++ { | 
|  | if s[i] >= utf8.RuneSelf { | 
|  | return false | 
|  | } | 
|  | } | 
|  | return true | 
|  | } |