github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/idna/idna.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package idna implements IDNA2008 (Internationalized Domain Names for
     6  // Applications), defined in RFC 5890, RFC 5891, RFC 5892, RFC 5893 and
     7  // RFC 5894.
     8  package idna // import "golang.org/x/net/idna"
     9  
    10  import (
    11  	"strings"
    12  	"unicode/utf8"
    13  )
    14  
    15  // TODO(nigeltao): specify when errors occur. For example, is ToASCII(".") or
    16  // ToASCII("foo\x00") an error? See also http://www.unicode.org/faq/idn.html#11
    17  
    18  // acePrefix is the ASCII Compatible Encoding prefix.
    19  const acePrefix = "xn--"
    20  
    21  // ToASCII converts a domain or domain label to its ASCII form. For example,
    22  // ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
    23  // ToASCII("golang") is "golang".
    24  func ToASCII(s string) (string, error) {
    25  	if ascii(s) {
    26  		return s, nil
    27  	}
    28  	labels := strings.Split(s, ".")
    29  	for i, label := range labels {
    30  		if !ascii(label) {
    31  			a, err := encode(acePrefix, label)
    32  			if err != nil {
    33  				return "", err
    34  			}
    35  			labels[i] = a
    36  		}
    37  	}
    38  	return strings.Join(labels, "."), nil
    39  }
    40  
    41  // ToUnicode converts a domain or domain label to its Unicode form. For example,
    42  // ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
    43  // ToUnicode("golang") is "golang".
    44  func ToUnicode(s string) (string, error) {
    45  	if !strings.Contains(s, acePrefix) {
    46  		return s, nil
    47  	}
    48  	labels := strings.Split(s, ".")
    49  	for i, label := range labels {
    50  		if strings.HasPrefix(label, acePrefix) {
    51  			u, err := decode(label[len(acePrefix):])
    52  			if err != nil {
    53  				return "", err
    54  			}
    55  			labels[i] = u
    56  		}
    57  	}
    58  	return strings.Join(labels, "."), nil
    59  }
    60  
    61  func ascii(s string) bool {
    62  	for i := 0; i < len(s); i++ {
    63  		if s[i] >= utf8.RuneSelf {
    64  			return false
    65  		}
    66  	}
    67  	return true
    68  }