func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
	if m.Prompt == nil {
		return nil, errors.New("acme/autocert: Manager.Prompt not set")
	}
	name := hello.ServerName
	if name == "" {
		return nil, errors.New("acme/autocert: missing server name")
	}
	if !strings.Contains(strings.Trim(name, "."), ".") {
		return nil, errors.New("acme/autocert: server name component count invalid")
	}
	name, err := idna.Lookup.ToASCII(name)
	if err != nil {
		return nil, errors.New("acme/autocert: server name contains invalid character")
	}
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
	defer cancel()
	if wantsTokenCert(hello) {
		m.tokensMu.RLock()
		defer m.tokensMu.RUnlock()
		if cert := m.certTokens[name]; cert != nil {
			return cert, nil
		}
		if cert, err := m.cacheGet(ctx, certKey{domain: name, isToken: true}); err == nil {
			return cert, nil
		}
		return nil, fmt.Errorf("acme/autocert: no token cert for %q", name)
	}
	ck := certKey{
		domain: strings.TrimSuffix(name, "."),  
		isRSA:  !supportsECDSA(hello),
	}
	cert, err := m.cert(ctx, ck)
	if err == nil {
		return cert, nil
	}
	if err != ErrCacheMiss {
		return nil, err
	}
	if err := m.hostPolicy()(ctx, name); err != nil {
		return nil, err
	}
	cert, err = m.createCert(ctx, ck)
	if err != nil {
		return nil, err
	}
	m.cachePut(ctx, ck, cert)
	return cert, nil
}
GetCertificate implements the tls.Config.GetCertificate hook.
It provides a TLS certificate for hello.ServerName host, including answering
tls-alpn-01 and *.acme.invalid (tls-sni-01 and tls-sni-02) challenges.
All other fields of hello are ignored.

If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting
a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.
The error is propagated back to the caller of GetCertificate and is user-visible.
This does not affect cached certs. See HostPolicy field description for more details.

If GetCertificate is used directly, instead of via Manager.TLSConfig, package users will
also have to add acme.ALPNProto to NextProtos for tls-alpn-01, or use HTTPHandler
for http-01. (The tls-sni-* challenges have been deprecated by popular ACME providers
due to security issues in the ecosystem.)
package autocert
import (
	"bytes"
	"context"
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"errors"
	"fmt"
	"io"
	mathrand "math/rand"
	"net"
	"net/http"
	"path"
	"strings"
	"sync"
	"time"
	"golang.org/x/crypto/acme"
	"golang.org/x/net/idna"
)
var createCertRetryAfter = time.Minute
var pseudoRand *lockedMathRand
func init() {
	src := mathrand.NewSource(time.Now().UnixNano())
	pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
}
func AcceptTOS(tosURL string) bool { return true }
type HostPolicy func(ctx context.Context, host string) error
func HostWhitelist(hosts ...string) HostPolicy {
	whitelist := make(map[string]bool, len(hosts))
	for _, h := range hosts {
		if h, err := idna.Lookup.ToASCII(h); err == nil {
			whitelist[h] = true
		}
	}
	return func(_ context.Context, host string) error {
		if !whitelist[host] {
			return fmt.Errorf("acme/autocert: host %q not configured in HostWhitelist", host)
		}
		return nil
	}
}
func defaultHostPolicy(context.Context, string) error {
	return nil
}
type Manager struct {
	Prompt func(tosURL string) bool
	Cache Cache
	HostPolicy HostPolicy
	RenewBefore time.Duration
	Client *acme.Client
	Email string
	ForceRSA bool
	ExtraExtensions []pkix.Extension
	clientMu sync.Mutex
	client   *acme.Client  
	stateMu sync.Mutex
	state   map[certKey]*certState
	renewalMu sync.Mutex
	renewal   map[certKey]*domainRenewal
	tokensMu sync.RWMutex
	tryHTTP01 bool
	httpTokens map[string][]byte
	certTokens map[string]*tls.Certificate
	nowFunc func() time.Time
}
type certKey struct {
	domain  string  
	isRSA   bool    
	isToken bool    
}
func (c certKey) String() string {
	if c.isToken {
		return c.domain + "+token"
	}
	if c.isRSA {
		return c.domain + "+rsa"
	}
	return c.domain
}
func (m *Manager) TLSConfig() *tls.Config {
	return &tls.Config{
		GetCertificate: m.GetCertificate,
		NextProtos: []string{
			"h2", "http/1.1",  
			acme.ALPNProto,  
		},
	}
}