github.com/golazy/golazy@v0.0.7-0.20221012133820-968fe65a0b65/lazydev/child.go (about)

     1  package lazydev
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"fmt"
     7  	"log"
     8  	"net"
     9  	"net/http"
    10  	"os"
    11  	"os/signal"
    12  
    13  	"github.com/adrg/xdg"
    14  	"github.com/golazy/golazy/lazydev/autocerts"
    15  	"github.com/golazy/golazy/lazydev/protocolmux"
    16  )
    17  
    18  type child struct {
    19  }
    20  
    21  func (s *child) Serve(h http.Handler) error {
    22  
    23  	listenerFile := os.NewFile(3, "listener")
    24  	if listenerFile == nil {
    25  		return fmt.Errorf("Expecting listener in FD 3")
    26  	}
    27  
    28  	l, err := net.FileListener(listenerFile)
    29  	if err != nil {
    30  		return err
    31  	}
    32  	pm := protocolmux.Mux{L: l}
    33  
    34  	// Setup http server
    35  	httpServer := http.Server{
    36  		Handler: h,
    37  	}
    38  
    39  	go func() {
    40  		err := httpServer.Serve(pm.ListenTo(protocolmux.HTTPPrefix))
    41  		if err != nil && err != http.ErrServerClosed {
    42  			panic(err)
    43  		}
    44  	}()
    45  
    46  	// Setup https server
    47  	cert, err := xdg.DataFile("golazy/golazy.pem")
    48  	if err != nil {
    49  		cert = "golazy.pem"
    50  	}
    51  	log.Println("Certificate Authority stored in:", cert)
    52  
    53  	ac, err := autocerts.LoadOrCreate(cert, nil)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	log.Println("ac", ac)
    59  
    60  	certPool := x509.NewCertPool()
    61  	certPool.AddCert(ac.CACert())
    62  
    63  	httpsServer := http.Server{
    64  		Handler: h,
    65  		TLSConfig: &tls.Config{
    66  			GetCertificate: ac.CertificateFromHello,
    67  			RootCAs:        certPool,
    68  		},
    69  	}
    70  
    71  	log.Println("https server", httpsServer)
    72  
    73  	go func() {
    74  		log.Println("Starting https server")
    75  		err := httpsServer.ServeTLS(pm.ListenTo(protocolmux.TLSPrefix), "", "")
    76  		if err != nil && err != http.ErrServerClosed {
    77  			panic(err)
    78  		}
    79  		log.Println("done with https")
    80  	}()
    81  
    82  	err = pm.Listen()
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	c := make(chan os.Signal, 1)
    88  	signal.Notify(c, os.Interrupt)
    89  
    90  	log.Println("Ready")
    91  	<-c
    92  	log.Println("Got interrupt signal")
    93  
    94  	return nil
    95  }