mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 12:42:34 +02:00
140 lines
No EOL
2.9 KiB
Go
140 lines
No EOL
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
type Server struct {
|
|
Name string
|
|
KeyFile string
|
|
CertFile string
|
|
CertProvider AutoCertProvider
|
|
http *http.Server
|
|
https *http.Server
|
|
httpStarted bool
|
|
httpsStarted bool
|
|
}
|
|
|
|
type ServerOptions struct {
|
|
Name string
|
|
HTTPAddr string
|
|
HTTPSAddr string
|
|
CertProvider AutoCertProvider
|
|
RedirectToHTTPS bool
|
|
Handler http.Handler
|
|
}
|
|
|
|
type LogrusWrapper struct {
|
|
l *logrus.Entry
|
|
}
|
|
|
|
func (l LogrusWrapper) Write(b []byte) (int, error) {
|
|
return l.l.Logger.WriterLevel(logrus.ErrorLevel).Write(b)
|
|
}
|
|
|
|
func NewServer(opt ServerOptions) *Server {
|
|
var httpHandler http.Handler
|
|
var s *Server
|
|
if opt.RedirectToHTTPS {
|
|
httpHandler = http.HandlerFunc(redirectToTLSHandler)
|
|
} else {
|
|
httpHandler = opt.Handler
|
|
}
|
|
logger := log.Default()
|
|
logger.SetOutput(LogrusWrapper{
|
|
logrus.WithFields(logrus.Fields{"component": "server", "name": opt.Name}),
|
|
})
|
|
if opt.CertProvider != nil {
|
|
s = &Server{
|
|
Name: opt.Name,
|
|
CertProvider: opt.CertProvider,
|
|
http: &http.Server{
|
|
Addr: opt.HTTPAddr,
|
|
Handler: httpHandler,
|
|
ErrorLog: logger,
|
|
},
|
|
https: &http.Server{
|
|
Addr: opt.HTTPSAddr,
|
|
Handler: opt.Handler,
|
|
ErrorLog: logger,
|
|
TLSConfig: &tls.Config{
|
|
GetCertificate: opt.CertProvider.GetCert,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
s = &Server{
|
|
Name: opt.Name,
|
|
KeyFile: keyFileDefault,
|
|
CertFile: certFileDefault,
|
|
http: &http.Server{
|
|
Addr: opt.HTTPAddr,
|
|
Handler: httpHandler,
|
|
ErrorLog: logger,
|
|
},
|
|
https: &http.Server{
|
|
Addr: opt.HTTPSAddr,
|
|
Handler: opt.Handler,
|
|
ErrorLog: logger,
|
|
},
|
|
}
|
|
if !s.certsOK() {
|
|
s.http.Handler = opt.Handler
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (s *Server) Start() {
|
|
if s.http != nil {
|
|
s.httpStarted = true
|
|
logrus.Printf("starting http %s server on %s", s.Name, s.http.Addr)
|
|
go func() {
|
|
err := s.http.ListenAndServe()
|
|
s.handleErr("http", err)
|
|
}()
|
|
}
|
|
|
|
if s.https != nil && (s.CertProvider != nil || s.certsOK()) {
|
|
s.httpsStarted = true
|
|
logrus.Printf("starting https %s server on %s", s.Name, s.https.Addr)
|
|
go func() {
|
|
err := s.https.ListenAndServeTLS(s.CertFile, s.KeyFile)
|
|
s.handleErr("https", err)
|
|
}()
|
|
}
|
|
}
|
|
|
|
func (s *Server) Stop() {
|
|
ctx, _ := context.WithTimeout(context.Background(), 3*time.Second)
|
|
|
|
if s.httpStarted {
|
|
errHTTP := s.http.Shutdown(ctx)
|
|
s.handleErr("http", errHTTP)
|
|
s.httpStarted = false
|
|
}
|
|
|
|
if s.httpsStarted {
|
|
errHTTPS := s.https.Shutdown(ctx)
|
|
s.handleErr("https", errHTTPS)
|
|
s.httpsStarted = false
|
|
}
|
|
}
|
|
|
|
func (s *Server) handleErr(scheme string, err error) {
|
|
switch err {
|
|
case nil, http.ErrServerClosed:
|
|
return
|
|
default:
|
|
logrus.Fatalf("failed to start %s %s server: %v", scheme, s.Name, err)
|
|
}
|
|
}
|
|
|
|
func (s *Server) certsOK() bool {
|
|
return utils.fileOK(s.CertFile) && utils.fileOK(s.KeyFile)
|
|
} |