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.
94 lines
2.3 KiB
94 lines
2.3 KiB
1 year ago
|
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...)
|
||
|
}
|