or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bpf.mdcontext-ctxhttp.mdcontext.mddict.mddns-dnsmessage.mdhtml-atom.mdhtml-charset.mdhtml.mdhttp-httpguts.mdhttp-httpproxy.mdhttp2-h2c.mdhttp2-hpack.mdhttp2.mdicmp.mdidna.mdindex.mdipv4.mdipv6.mdnettest.mdnetutil.mdproxy.mdpublicsuffix.mdquic-qlog.mdquic.mdtrace.mdwebdav.mdwebsocket.mdxsrftoken.md
tile.json

idna.mddocs/

Internationalized Domain Names

Package idna implements IDNA2008 using the compatibility processing defined by UTS (Unicode Technical Standard) #46, which defines a standard to deal with the transition from IDNA2003.

IDNA2008 (Internationalized Domain Names for Applications) is defined in RFC 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.

Import

import "golang.org/x/net/idna"

Constants

// UnicodeVersion is the Unicode version from which the tables in this package are derived
const UnicodeVersion = "15.0.0"

Variables

var (
    // Punycode is a Profile that does raw punycode processing with minimal validation
    Punycode *Profile = punycode

    // Lookup is the recommended profile for looking up domain names (RFC 5891 Section 5)
    Lookup *Profile = lookup

    // Display is the recommended profile for displaying domain names
    Display *Profile = display

    // Registration is the recommended profile for checking whether an IDN is valid for registration
    Registration *Profile = registration
)

Functions

// New creates a new Profile
func New(o ...Option) *Profile

// ToASCII is a wrapper for Punycode.ToASCII
func ToASCII(s string) (string, error)

// ToUnicode is a wrapper for Punycode.ToUnicode
func ToUnicode(s string) (string, error)

Types

Profile

// Profile defines the configuration of an IDNA mapper
type Profile struct {
    // Has unexported fields
}

func (p *Profile) String() string
func (p *Profile) ToASCII(s string) (string, error)
func (p *Profile) ToUnicode(s string) (string, error)

Option

// Option configures a Profile at creation time
type Option func(*options)

// BidiRule enables the Bidi rule as defined in RFC 5893
func BidiRule() Option

// CheckHyphens sets whether to check for correct use of hyphens in labels
func CheckHyphens(enable bool) Option

// CheckJoiners sets whether to check the ContextJ rules (RFC 5892 Appendix A)
func CheckJoiners(enable bool) Option

// MapForLookup sets validation and mapping options for domain name lookup
func MapForLookup() Option

// RemoveLeadingDots removes leading label separators
func RemoveLeadingDots(remove bool) Option

// StrictDomainName limits the set of permissible ASCII characters
func StrictDomainName(use bool) Option

// Transitional sets a Profile to use the Transitional mapping
func Transitional(transitional bool) Option

// ValidateForRegistration sets validation options for registration
func ValidateForRegistration() Option

// ValidateLabels sets whether to check the mandatory label validation criteria
func ValidateLabels(enable bool) Option

// VerifyDNSLength sets whether a Profile should fail if any IDN parts are too long
func VerifyDNSLength(verify bool) Option

Usage Examples

Converting Domain Names

import (
    "fmt"
    "golang.org/x/net/idna"
)

func convertDomain() {
    // Convert Unicode domain to ASCII (Punycode)
    ascii, err := idna.ToASCII("münchen.de")
    if err != nil {
        panic(err)
    }
    fmt.Println("ASCII:", ascii) // "xn--mnchen-3ya.de"

    // Convert ASCII (Punycode) to Unicode
    unicode, err := idna.ToUnicode("xn--mnchen-3ya.de")
    if err != nil {
        panic(err)
    }
    fmt.Println("Unicode:", unicode) // "münchen.de"
}

Using Profiles

func lookupDomain(domain string) error {
    // Use Lookup profile for domain name resolution
    ascii, err := idna.Lookup.ToASCII(domain)
    if err != nil {
        return fmt.Errorf("invalid domain: %w", err)
    }

    fmt.Printf("Lookup domain: %s\n", ascii)

    // Perform DNS lookup with ASCII domain
    // ...

    return nil
}

func displayDomain(domain string) (string, error) {
    // Use Display profile for showing domains to users
    displayName, err := idna.Display.ToUnicode(domain)
    if err != nil {
        return "", err
    }

    return displayName, nil
}

Domain Validation

func validateForRegistration(domain string) error {
    // Use Registration profile to check if domain is valid for registration
    _, err := idna.Registration.ToASCII(domain)
    if err != nil {
        return fmt.Errorf("domain not valid for registration: %w", err)
    }

    return nil
}

Handling Internationalized Domains in HTTP

import (
    "golang.org/x/net/idna"
    "net/http"
    "net/url"
)

func makeRequest(unicodeDomain, path string) error {
    // Convert Unicode domain to ASCII for HTTP request
    asciiDomain, err := idna.ToASCII(unicodeDomain)
    if err != nil {
        return err
    }

    // Build URL with ASCII domain
    u := &url.URL{
        Scheme: "https",
        Host:   asciiDomain,
        Path:   path,
    }

    resp, err := http.Get(u.String())
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    // Process response...
    return nil
}

// Usage:
// makeRequest("münchen.de", "/index.html")

Bidirectional Text Support

func validateWithBidiRule(domain string) error {
    // Create profile with Bidi rule for proper validation
    profile := idna.New(
        idna.MapForLookup(),
        idna.BidiRule(),
    )

    _, err := profile.ToASCII(domain)
    if err != nil {
        return fmt.Errorf("domain fails Bidi validation: %w", err)
    }

    return nil
}

URL Normalization

func normalizeURL(rawURL string) (string, error) {
    u, err := url.Parse(rawURL)
    if err != nil {
        return "", err
    }

    // Convert host to ASCII form
    if u.Host != "" {
        asciiHost, err := idna.ToASCII(u.Host)
        if err != nil {
            return "", fmt.Errorf("invalid host: %w", err)
        }
        u.Host = asciiHost
    }

    return u.String(), nil
}

// Usage:
// normalized, err := normalizeURL("https://münchen.de/path")
// Result: "https://xn--mnchen-3ya.de/path"