You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

93 lines
2.3 KiB

package rest
import (
"crypto/tls"
"git.diulo.com/mogfee/kit/rest/chain"
"git.diulo.com/mogfee/kit/rest/httpx"
"git.diulo.com/mogfee/kit/rest/internal"
"net/http"
"time"
)
type engine struct {
conf RestConf
routes []featureRoutes
timeout time.Duration
chain chain.Chain
middlewares []Middleware
tlsConfig *tls.Config
}
func newEngine(c RestConf) *engine {
srv := &engine{
conf: c,
timeout: time.Duration(c.Timeout),
middlewares: make([]Middleware, 0),
}
return srv
}
func (n *engine) addRoutes(r featureRoutes) {
n.routes = append(n.routes, r)
if r.timeout > n.timeout {
n.timeout = r.timeout
}
}
func (n *engine) bindRoutes(router httpx.Router) error {
for _, fr := range n.routes {
for _, route := range fr.routes {
if err := n.bindRoute(fr, router, route); err != nil {
return err
}
}
}
return nil
}
func (n *engine) bindRoute(fr featureRoutes, router httpx.Router, route Route) error {
chn := n.chain
if chn == nil {
chn = n.buildChainWithNativeMiddlewares(fr, route)
}
for _, middleware := range n.middlewares {
chn = chn.Append(convertMiddleware(middleware))
}
handle := chn.ThenFunc(route.Handler)
return router.Handle(route.Method, route.Path, handle)
}
func (n *engine) buildChainWithNativeMiddlewares(fr featureRoutes, route Route) chain.Chain {
chn := chain.New()
return chn
}
func convertMiddleware(ware Middleware) func(http.Handler) http.Handler {
return func(handler http.Handler) http.Handler {
return ware(handler.ServeHTTP)
}
}
func (n *engine) start(router httpx.Router) error {
err := n.bindRoutes(router)
if err != nil {
return err
}
if len(n.conf.CertFile) == 0 && len(n.conf.KeyFile) == 0 {
return internal.StartHttp(n.conf.Host, n.conf.Port, router, n.withTimeout())
}
return internal.StartHttps(n.conf.Host, n.conf.Port, n.conf.CertFile,
n.conf.KeyFile, router, func(svr *http.Server) {
if n.tlsConfig != nil {
svr.TLSConfig = n.tlsConfig
}
}, n.withTimeout())
}
func (n *engine) withTimeout() internal.StartOption {
return func(svr *http.Server) {
timeout := n.timeout
if timeout > 0 {
svr.ReadTimeout = 4 * timeout / 5
svr.WriteTimeout = 11 * timeout / 10
}
}
}
func (n *engine) use(middleware ...Middleware) {
n.middlewares = append(n.middlewares, middleware...)
}