1
0
mirror of https://github.com/labstack/echo.git synced 2025-07-15 01:34:53 +02:00

refactored start server functions

Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
Vishal Rana
2016-11-04 18:51:17 -07:00
parent 4f1aef1469
commit 409c5a42b7

110
echo.go
View File

@ -53,38 +53,32 @@ import (
"sync" "sync"
"time" "time"
"github.com/rsc/letsencrypt"
"github.com/labstack/gommon/color" "github.com/labstack/gommon/color"
glog "github.com/labstack/gommon/log" glog "github.com/labstack/gommon/log"
"github.com/rsc/letsencrypt"
"github.com/tylerb/graceful" "github.com/tylerb/graceful"
) )
type ( type (
// Echo is the top-level framework instance. // Echo is the top-level framework instance.
Echo struct { Echo struct {
Server *http.Server
TLSServer *http.Server
TLSConfig *tls.Config
TLSCacheFile string
TLSHosts []string
ShutdownTimeout time.Duration
DisableHTTP2 bool DisableHTTP2 bool
Debug bool Debug bool
HTTPErrorHandler HTTPErrorHandler
Binder Binder Binder Binder
Renderer Renderer Renderer Renderer
ShutdownTimeout time.Duration
Color *color.Color
Logger Logger Logger Logger
server *graceful.Server
tlsServer *graceful.Server
tlsManager letsencrypt.Manager tlsManager letsencrypt.Manager
graceful *graceful.Server
gracefulTLS *graceful.Server
premiddleware []MiddlewareFunc premiddleware []MiddlewareFunc
middleware []MiddlewareFunc middleware []MiddlewareFunc
maxParam *int maxParam *int
router *Router router *Router
notFoundHandler HandlerFunc notFoundHandler HandlerFunc
pool sync.Pool pool sync.Pool
color *color.Color
} }
// Route contains a handler and information for matching against requests. // Route contains a handler and information for matching against requests.
@ -243,20 +237,12 @@ var (
) )
// New creates an instance of Echo. // New creates an instance of Echo.
func New() (e *Echo) { func New() (e *Echo) {
e = &Echo{ e = &Echo{
Server: new(http.Server),
TLSServer: new(http.Server),
// TODO: https://github.com/golang/go/commit/d24f446a90ea94b87591bf16228d7d871fec3d92
TLSConfig: new(tls.Config),
TLSCacheFile: "letsencrypt.cache",
ShutdownTimeout: 15 * time.Second, ShutdownTimeout: 15 * time.Second,
Logger: glog.New("echo"), Logger: glog.New("echo"),
graceful: new(graceful.Server),
gracefulTLS: new(graceful.Server),
maxParam: new(int), maxParam: new(int),
color: color.New(), Color: color.New(),
} }
e.HTTPErrorHandler = e.DefaultHTTPErrorHandler e.HTTPErrorHandler = e.DefaultHTTPErrorHandler
e.Binder = &binder{} e.Binder = &binder{}
@ -517,68 +503,74 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
e.pool.Put(c) e.pool.Put(c)
} }
func (e *Echo) config(gs *graceful.Server, s *http.Server, address string) {
e.color.SetOutput(e.Logger.Output())
gs.Server = s
gs.Addr = address
gs.Handler = e
gs.Timeout = e.ShutdownTimeout
gs.Logger = slog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0)
if gs == e.gracefulTLS && !e.DisableHTTP2 {
e.TLSConfig.NextProtos = append(e.TLSConfig.NextProtos, "h2")
}
}
// Start starts the HTTP server. // Start starts the HTTP server.
// Note: If custom `Echo#Server` is used, it's Addr and Handler properties are func (e *Echo) Start(address string) error {
// ignored. e.Color.Printf(" ⇛ http server started on %s\n", color.Green(address))
func (e *Echo) Start(address string) (err error) { return e.StartServer(&http.Server{Addr: address})
e.config(e.graceful, e.Server, address)
color.Printf(" ⇛ http server started on %s\n", color.Green(address))
return e.graceful.ListenAndServe()
} }
// StartTLS starts the TLS server. // StartTLS starts the HTTPS server.
// Note: If custom `Echo#TLSServer` is used, it's Addr and Handler properties are
// ignored.
func (e *Echo) StartTLS(address string, certFile, keyFile string) (err error) { func (e *Echo) StartTLS(address string, certFile, keyFile string) (err error) {
e.config(e.gracefulTLS, e.TLSServer, address)
if certFile == "" || keyFile == "" { if certFile == "" || keyFile == "" {
return errors.New("invalid tls configuration") return errors.New("invalid tls configuration")
} }
e.TLSConfig.Certificates = make([]tls.Certificate, 1) config := new(tls.Config)
e.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil { if err != nil {
return return
} }
color.Printf(" ⇛ https server started on %s\n", color.Green(address)) e.Color.Printf(" ⇛ https server started on %s\n", color.Green(address))
return e.gracefulTLS.ListenAndServeTLSConfig(e.TLSConfig) return e.startTLS(address, config)
} }
// StartAutoTLS starts the TLS server using certificates automatically from https://letsencrypt.org. // StartAutoTLS starts the HTTPS server using certificates automatically from https://letsencrypt.org.
// Note: If custom `Echo#TLSServer` is used, it's Addr and Handler properties are func (e *Echo) StartAutoTLS(hosts []string, cacheFile string) (err error) {
// ignored.
func (e *Echo) StartAutoTLS() (err error) {
address := ":443" address := ":443"
e.config(e.gracefulTLS, e.TLSServer, address) config := new(tls.Config)
e.TLSConfig.GetCertificate = e.tlsManager.GetCertificate config.GetCertificate = e.tlsManager.GetCertificate
if err = e.tlsManager.CacheFile(e.TLSCacheFile); err != nil { e.tlsManager.SetHosts(hosts) // Added security
if err = e.tlsManager.CacheFile(cacheFile); err != nil {
return return
} }
// NOTE: Added security e.Color.Printf(" ⇛ https auto https server started on %s\n", color.Green(address))
e.tlsManager.SetHosts(e.TLSHosts) return e.startTLS(address, config)
color.Printf(" ⇛ https auto tls server started on %s\n", color.Green(address)) }
return e.gracefulTLS.ListenAndServeTLSConfig(e.TLSConfig)
func (e *Echo) startTLS(address string, config *tls.Config) error {
if !e.DisableHTTP2 {
config.NextProtos = append(config.NextProtos, "h2")
}
return e.StartServer(&http.Server{
Addr: address,
TLSConfig: config,
})
}
// StartServer runs a custom HTTP server.
func (e *Echo) StartServer(s *http.Server) error {
s.Handler = e
gs := &graceful.Server{
Server: s,
Timeout: e.ShutdownTimeout,
Logger: slog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0),
}
if s.TLSConfig == nil {
e.server = gs
} else {
e.tlsServer = gs
}
return gs.ListenAndServe()
} }
// Shutdown gracefully shutdown the HTTP server with timeout. // Shutdown gracefully shutdown the HTTP server with timeout.
func (e *Echo) Shutdown(timeout time.Duration) { func (e *Echo) Shutdown(timeout time.Duration) {
e.graceful.Stop(timeout) e.server.Stop(timeout)
} }
// ShutdownTLS gracefully shutdown the TLS server with timeout. // ShutdownTLS gracefully shutdown the TLS server with timeout.
func (e *Echo) ShutdownTLS(timeout time.Duration) { func (e *Echo) ShutdownTLS(timeout time.Duration) {
e.gracefulTLS.Stop(timeout) e.tlsServer.Stop(timeout)
} }
// NewHTTPError creates a new HTTPError instance. // NewHTTPError creates a new HTTPError instance.