func (m *Manager) Register(email string, prompt func(string) bool) error {
	m.init()
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.register(email, prompt)
}
Register registers the manager with letsencrypt.org, using the given email address.
Registration may require agreeing to the letsencrypt.org terms of service.
If so, Register calls prompt(url) where url is the URL of the terms of service.
Prompt should report whether the caller agrees to the terms.
A nil prompt func is taken to mean that the user always agrees.
The email address is sent to LetsEncrypt.org but otherwise unchecked;
it can be omitted by passing the empty string.

Calling Register is only required to make sure registration uses a
particular email address or to insert an explicit prompt into the
registration sequence. If the manager is not registered, it will
automatically register with no email address and automatic
agreement to the terms of service at the first call to Cert or GetCertificate.
package letsencrypt
import (
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"
	"github.com/ossrs/go-oryx-lib/https/net/context"
	"github.com/ossrs/go-oryx-lib/https/time/rate"
	"github.com/ossrs/go-oryx-lib/https/acme"
)
const letsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"
const debug = false
type Manager struct {
	mu           sync.Mutex
	state        state
	rateLimit    *rate.Limiter
	newHostLimit *rate.Limiter
	certCache    map[string]*cacheEntry
	certTokens   map[string]*tls.Certificate
	watchChan    chan struct{}
}
func (m *Manager) Serve() error {
	l, err := net.Listen("tcp", ":http")
	if err != nil {
		return err
	}
	defer l.Close()
	go http.Serve(l, http.HandlerFunc(RedirectHTTP))
	return m.ServeHTTPS()
}
func (m *Manager) ServeHTTPS() error {
	srv := &http.Server{
		Addr: ":https",
		TLSConfig: &tls.Config{
			GetCertificate: m.GetCertificate,
		},
	}
	return srv.ListenAndServeTLS("", "")
}
func RedirectHTTP(w http.ResponseWriter, r *http.Request) {
	if r.TLS != nil || r.Host == "" {
		http.Error(w, "not found", 404)
	}
	u := r.URL
	u.Host = r.Host
	u.Scheme = "https"
	http.Redirect(w, r, u.String(), 302)
}
type state struct {
	Email string
	Reg   *acme.RegistrationResource
	Key   string
	key   *ecdsa.PrivateKey
	Hosts []string
	Certs map[string]stateCert
}
func (s *state) GetEmail() string                            { return s.Email }
func (s *state) GetRegistration() *acme.RegistrationResource { return s.Reg }
func (s *state) GetPrivateKey() crypto.PrivateKey            { return s.key }
type stateCert struct {
	Cert string
	Key  string
}
func (cert stateCert) toTLS() (*tls.Certificate, error) {
	c, err := tls.X509KeyPair([]byte(cert.Cert), []byte(cert.Key))
	if err != nil {
		return nil, err
	}
	return &c, err
}
type cacheEntry struct {
	host string
	m    *Manager
	mu         sync.Mutex
	cert       *tls.Certificate
	timeout    time.Time
	refreshing bool
	err        error
}
func (m *Manager) init() {
	m.mu.Lock()
	if m.certCache == nil {
		m.rateLimit = rate.NewLimiter(rate.Every(1*time.Minute), 20)
		m.newHostLimit = rate.NewLimiter(rate.Every(3*time.Hour), 20)
		m.certCache = map[string]*cacheEntry{}
		m.certTokens = map[string]*tls.Certificate{}
		m.watchChan = make(chan struct{}, 1)
		m.watchChan <- struct{}{}
	}
	m.mu.Unlock()
}
func (m *Manager) Watch() <-chan struct{} {
	m.init()
	m.updated()
	return m.watchChan
}
func (m *Manager) updated() {
	select {
	case m.watchChan <- struct{}{}:
	default:
	}
}
func (m *Manager) CacheFile(name string) error {
	f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, 0600)
	if err != nil {
		return err
	}
	f.Close()
	data, err := ioutil.ReadFile(name)
	if err != nil {
		return err
	}
	if len(data) > 0 {
		if err := m.Unmarshal(string(data)); err != nil {
			return err
		}
	}
	go func() {
		for range m.Watch() {
			err := ioutil.WriteFile(name, []byte(m.Marshal()), 0600)
			if err != nil {
				log.Printf("writing letsencrypt cache: %v", err)
			}
		}
	}()
	return nil
}
func (m *Manager) Registered() bool {
	m.init()
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.registered()
}
func (m *Manager) registered() bool {
	return m.state.Reg != nil && m.state.Reg.Body.Agreement != ""
}