add let's encrypt support
Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
parent
087b68e14d
commit
6e484e5c2d
18 changed files with 556 additions and 172 deletions
72
server.go
72
server.go
|
@ -34,7 +34,7 @@ var oxyLogger = &OxyLogger{}
|
|||
|
||||
// Server is the reverse-proxy/load-balancer engine
|
||||
type Server struct {
|
||||
serverEntryPoints map[string]serverEntryPoint
|
||||
serverEntryPoints serverEntryPoints
|
||||
configurationChan chan types.ConfigMessage
|
||||
configurationValidatedChan chan types.ConfigMessage
|
||||
signals chan os.Signal
|
||||
|
@ -46,6 +46,8 @@ type Server struct {
|
|||
loggerMiddleware *middlewares.Logger
|
||||
}
|
||||
|
||||
type serverEntryPoints map[string]*serverEntryPoint
|
||||
|
||||
type serverEntryPoint struct {
|
||||
httpServer *manners.GracefulServer
|
||||
httpRouter *middlewares.HandlerSwitcher
|
||||
|
@ -55,7 +57,7 @@ type serverEntryPoint struct {
|
|||
func NewServer(globalConfiguration GlobalConfiguration) *Server {
|
||||
server := new(Server)
|
||||
|
||||
server.serverEntryPoints = make(map[string]serverEntryPoint)
|
||||
server.serverEntryPoints = make(map[string]*serverEntryPoint)
|
||||
server.configurationChan = make(chan types.ConfigMessage, 10)
|
||||
server.configurationValidatedChan = make(chan types.ConfigMessage, 10)
|
||||
server.signals = make(chan os.Signal, 1)
|
||||
|
@ -71,6 +73,7 @@ func NewServer(globalConfiguration GlobalConfiguration) *Server {
|
|||
|
||||
// Start starts the server and blocks until server is shutted down.
|
||||
func (server *Server) Start() {
|
||||
server.startHTTPServers()
|
||||
go server.listenProviders()
|
||||
go server.listenConfigurations()
|
||||
server.configureProviders()
|
||||
|
@ -96,6 +99,19 @@ func (server *Server) Close() {
|
|||
server.loggerMiddleware.Close()
|
||||
}
|
||||
|
||||
func (server *Server) startHTTPServers() {
|
||||
server.serverEntryPoints = server.buildEntryPoints(server.globalConfiguration)
|
||||
for newServerEntryPointName, newServerEntryPoint := range server.serverEntryPoints {
|
||||
newsrv, err := server.prepareServer(newServerEntryPoint.httpRouter, server.globalConfiguration.EntryPoints[newServerEntryPointName], nil, server.loggerMiddleware, metrics)
|
||||
if err != nil {
|
||||
log.Fatal("Error preparing server: ", err)
|
||||
}
|
||||
serverEntryPoint := server.serverEntryPoints[newServerEntryPointName]
|
||||
serverEntryPoint.httpServer = newsrv
|
||||
go server.startServer(serverEntryPoint.httpServer, server.globalConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
func (server *Server) listenProviders() {
|
||||
lastReceivedConfiguration := time.Unix(0, 0)
|
||||
lastConfigs := make(map[string]*types.ConfigMessage)
|
||||
|
@ -141,22 +157,8 @@ func (server *Server) listenConfigurations() {
|
|||
if err == nil {
|
||||
server.serverLock.Lock()
|
||||
for newServerEntryPointName, newServerEntryPoint := range newServerEntryPoints {
|
||||
currentServerEntryPoint := server.serverEntryPoints[newServerEntryPointName]
|
||||
if currentServerEntryPoint.httpServer == nil {
|
||||
newsrv, err := server.prepareServer(newServerEntryPoint.httpRouter, server.globalConfiguration.EntryPoints[newServerEntryPointName], nil, server.loggerMiddleware, metrics)
|
||||
if err != nil {
|
||||
log.Fatal("Error preparing server: ", err)
|
||||
}
|
||||
go server.startServer(newsrv, server.globalConfiguration)
|
||||
currentServerEntryPoint.httpServer = newsrv
|
||||
currentServerEntryPoint.httpRouter = newServerEntryPoint.httpRouter
|
||||
server.serverEntryPoints[newServerEntryPointName] = currentServerEntryPoint
|
||||
log.Infof("Created new Handler: %p", newServerEntryPoint.httpRouter.GetHandler())
|
||||
} else {
|
||||
handlerSwitcher := currentServerEntryPoint.httpRouter
|
||||
handlerSwitcher.UpdateHandler(newServerEntryPoint.httpRouter.GetHandler())
|
||||
log.Infof("Created new Handler: %p", newServerEntryPoint.httpRouter.GetHandler())
|
||||
}
|
||||
server.serverEntryPoints[newServerEntryPointName].httpRouter.UpdateHandler(newServerEntryPoint.httpRouter.GetHandler())
|
||||
log.Infof("Server configurartion reloaded on %s", server.serverEntryPoints[newServerEntryPointName].httpServer.Addr)
|
||||
}
|
||||
server.currentConfigurations = newConfigurations
|
||||
server.serverLock.Unlock()
|
||||
|
@ -222,19 +224,21 @@ func (server *Server) listenSignals() {
|
|||
}
|
||||
|
||||
// creates a TLS config that allows terminating HTTPS for multiple domains using SNI
|
||||
func (server *Server) createTLSConfig(tlsOption *TLS) (*tls.Config, error) {
|
||||
func (server *Server) createTLSConfig(tlsOption *TLS, router *middlewares.HandlerSwitcher) (*tls.Config, error) {
|
||||
if tlsOption == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if server.globalConfiguration.ACME != nil {
|
||||
if acmeEntrypoint, ok := server.serverEntryPoints[server.globalConfiguration.ACME.EntryPoint]; ok {
|
||||
return server.globalConfiguration.ACME.createACMEConfig(router, acmeEntrypoint.httpRouter)
|
||||
}
|
||||
return nil, errors.New("Unknown entrypoint " + server.globalConfiguration.ACME.EntryPoint + "for ACME configuration")
|
||||
}
|
||||
if len(tlsOption.Certificates) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
config := &tls.Config{}
|
||||
if config.NextProtos == nil {
|
||||
config.NextProtos = []string{"http/1.1"}
|
||||
}
|
||||
|
||||
var err error
|
||||
config.Certificates = make([]tls.Certificate, len(tlsOption.Certificates))
|
||||
for i, v := range tlsOption.Certificates {
|
||||
|
@ -250,30 +254,28 @@ func (server *Server) createTLSConfig(tlsOption *TLS) (*tls.Config, error) {
|
|||
}
|
||||
|
||||
func (server *Server) startServer(srv *manners.GracefulServer, globalConfiguration GlobalConfiguration) {
|
||||
log.Info("Starting server on ", srv.Addr)
|
||||
log.Infof("Starting server on %s", srv.Addr)
|
||||
if srv.TLSConfig != nil {
|
||||
err := srv.ListenAndServeTLSWithConfig(srv.TLSConfig)
|
||||
if err != nil {
|
||||
if err := srv.ListenAndServeTLSWithConfig(srv.TLSConfig); err != nil {
|
||||
log.Fatal("Error creating server: ", err)
|
||||
}
|
||||
} else {
|
||||
err := srv.ListenAndServe()
|
||||
if err != nil {
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
log.Fatal("Error creating server: ", err)
|
||||
}
|
||||
}
|
||||
log.Info("Server stopped")
|
||||
}
|
||||
|
||||
func (server *Server) prepareServer(router http.Handler, entryPoint *EntryPoint, oldServer *manners.GracefulServer, middlewares ...negroni.Handler) (*manners.GracefulServer, error) {
|
||||
log.Info("Preparing server")
|
||||
func (server *Server) prepareServer(router *middlewares.HandlerSwitcher, entryPoint *EntryPoint, oldServer *manners.GracefulServer, middlewares ...negroni.Handler) (*manners.GracefulServer, error) {
|
||||
log.Infof("Preparing server %+v", entryPoint)
|
||||
// middlewares
|
||||
var negroni = negroni.New()
|
||||
for _, middleware := range middlewares {
|
||||
negroni.Use(middleware)
|
||||
}
|
||||
negroni.UseHandler(router)
|
||||
tlsConfig, err := server.createTLSConfig(entryPoint.TLS)
|
||||
tlsConfig, err := server.createTLSConfig(entryPoint.TLS, router)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating TLS config %s", err)
|
||||
return nil, err
|
||||
|
@ -299,11 +301,11 @@ func (server *Server) prepareServer(router http.Handler, entryPoint *EntryPoint,
|
|||
return gracefulServer, nil
|
||||
}
|
||||
|
||||
func (server *Server) buildEntryPoints(globalConfiguration GlobalConfiguration) map[string]serverEntryPoint {
|
||||
serverEntryPoints := make(map[string]serverEntryPoint)
|
||||
func (server *Server) buildEntryPoints(globalConfiguration GlobalConfiguration) map[string]*serverEntryPoint {
|
||||
serverEntryPoints := make(map[string]*serverEntryPoint)
|
||||
for entryPointName := range globalConfiguration.EntryPoints {
|
||||
router := server.buildDefaultHTTPRouter()
|
||||
serverEntryPoints[entryPointName] = serverEntryPoint{
|
||||
serverEntryPoints[entryPointName] = &serverEntryPoint{
|
||||
httpRouter: middlewares.NewHandlerSwitcher(router),
|
||||
}
|
||||
}
|
||||
|
@ -312,7 +314,7 @@ func (server *Server) buildEntryPoints(globalConfiguration GlobalConfiguration)
|
|||
|
||||
// LoadConfig returns a new gorilla.mux Route from the specified global configuration and the dynamic
|
||||
// provider configurations.
|
||||
func (server *Server) loadConfig(configurations configs, globalConfiguration GlobalConfiguration) (map[string]serverEntryPoint, error) {
|
||||
func (server *Server) loadConfig(configurations configs, globalConfiguration GlobalConfiguration) (map[string]*serverEntryPoint, error) {
|
||||
serverEntryPoints := server.buildEntryPoints(globalConfiguration)
|
||||
redirectHandlers := make(map[string]http.Handler)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue