func serveBlacklistCertificates(w http.ResponseWriter, r *http.Request) {
	exceptions, err := getExceptionsFromBody(r)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	w.Header().Set("Content-Type", "application/x-pem-file")
	w.Header().Set("Content-Disposition", "inline; filename=\"certs.pem\"")
	certMapLock.RLock()
	certs.WriteCerts(w, certificates, certs.BlacklistMatcher(exceptions))
	certMapLock.RUnlock()
}
serveBlacklistCertificates serves certificates using a blacklist. The
expected form of the URL is: /generate/all/except/. We expect a request
body that contains a JSON list of exact labels to exclude.
package main
import (
	"encoding/json"
	"fmt"
	"github.com/Lukasa/mkcert/certs"
	"io"
	"log"
	"net/http"
	"runtime"
	"strings"
	"sync"
	"time"
)
const CERT_URL = "https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt"
var certificates certs.CertList = nil
var certMapLock *sync.RWMutex = new(sync.RWMutex)
type CertificateList struct {
	Certificates []string
}
func updateCertificates() {
	resp, err := http.Get(CERT_URL)
	if err != nil {
		log.Fatalf("Unable to get cert file: %s", err)
	}
	_, _, objects := certs.ParseInput(resp.Body)
	resp.Body.Close()
	certMapLock.Lock()
	certificates = certs.OutputTrustedCerts(objects)
	certMapLock.Unlock()
}
func certUpdateLoop() {
	for {
		updateCertificates()
		<-time.After(24 * time.Hour)
	}
}
func getExceptionsFromPath(path string, prefix string) map[string]interface{} {
	query := string(path[len(prefix):])
	components := strings.Split(query, "+")
	exceptions := make(map[string]interface{})
	for _, component := range components {
		exceptions[component] = nil
	}
	return exceptions
}
func getExceptionsFromBody(r *http.Request) (map[string]interface{}, error) {
	exceptions := make(map[string]interface{})
	if r.ContentLength == 0 {
		return exceptions, nil
	}
	decoder := json.NewDecoder(r.Body)
	var listExceptions []string
	err := decoder.Decode(&listExceptions)
	if err != nil && err != io.EOF {
		return exceptions, err
	}
	for _, exception := range listExceptions {
		exceptions[exception] = nil
	}
	return exceptions, nil
}