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.
122 lines
3.2 KiB
122 lines
3.2 KiB
1 year ago
|
package runtime
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/labstack/echo/v4"
|
||
|
"github.com/labstack/echo/v4/middleware"
|
||
|
"net"
|
||
|
"net/http"
|
||
|
"sorbet/internal/util"
|
||
|
"sorbet/pkg/env"
|
||
|
"sorbet/pkg/rsp"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// maxHeaderBytes is used by the http server to limit the size of request headers.
|
||
|
// This may need to be increased if accepting cookies from the public.
|
||
|
maxHeaderBytes = 1 << 20
|
||
|
// readTimeout is used by the http server to set a maximum duration before
|
||
|
// timing out read of the request. The default timeout is 10 seconds.
|
||
|
readTimeout = 10 * time.Second
|
||
|
// writeTimeout is used by the http server to set a maximum duration before
|
||
|
// timing out write of the response. The default timeout is 10 seconds.
|
||
|
writeTimeout = 10 * time.Second
|
||
|
// idleTimeout is used by the http server to set a maximum duration for
|
||
|
// keep-alive connections.
|
||
|
idleTimeout = 120 * time.Second
|
||
|
)
|
||
|
|
||
|
func newEchoFramework() (*echo.Echo, error) {
|
||
|
e := echo.New()
|
||
|
e.HideBanner = true
|
||
|
e.HidePort = true
|
||
|
e.HTTPErrorHandler = rsp.HTTPErrorHandler
|
||
|
e.Debug = !env.IsEnv("prod")
|
||
|
e.Logger = util.NewEchoLogger()
|
||
|
e.Use(middleware.Recover())
|
||
|
e.Use(middleware.CORS())
|
||
|
e.Use(middleware.Logger())
|
||
|
for _, servlet := range servlets {
|
||
|
group := e.Group("")
|
||
|
for _, routable := range servlet.Routes() {
|
||
|
routable.InitRoutes(group)
|
||
|
}
|
||
|
}
|
||
|
routes := e.Routes()
|
||
|
e.GET("/_routes", func(c echo.Context) error {
|
||
|
return c.JSON(http.StatusOK, routes)
|
||
|
})
|
||
|
return e, nil
|
||
|
}
|
||
|
|
||
|
func createServer() (*http.Server, net.Listener, error) {
|
||
|
e, err := newEchoFramework()
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
l, err := createTCPListener()
|
||
|
if err != nil {
|
||
|
return nil, nil, err
|
||
|
}
|
||
|
|
||
|
s := &http.Server{
|
||
|
Handler: e,
|
||
|
MaxHeaderBytes: env.Int("SERVER_MAX_HEADER_BYTES", maxHeaderBytes),
|
||
|
ReadTimeout: env.Duration("SERVER_READ_TIMEOUT", readTimeout),
|
||
|
WriteTimeout: env.Duration("SERVER_WRITE_TIMEOUT", writeTimeout),
|
||
|
IdleTimeout: env.Duration("SERVER_IDLE_TIMEOUT", idleTimeout),
|
||
|
}
|
||
|
|
||
|
return s, l, nil
|
||
|
}
|
||
|
|
||
|
func createTCPListener() (net.Listener, error) {
|
||
|
l, err := net.Listen(
|
||
|
env.String("SERVER_NETWORK", "tcp"),
|
||
|
fmt.Sprintf("%s:%d",
|
||
|
env.String("SERVER_ADDRESS", "0.0.0.0"),
|
||
|
env.Int("SERVER_PORT", 1324),
|
||
|
),
|
||
|
)
|
||
|
if err == nil {
|
||
|
l = net.Listener(TCPKeepAliveListener{
|
||
|
TCPListener: l.(*net.TCPListener),
|
||
|
})
|
||
|
}
|
||
|
return l, err
|
||
|
}
|
||
|
|
||
|
// TCPKeepAliveListener sets TCP keep-alive timeouts on accepted
|
||
|
// connections. It's used by ListenAndServe and ListenAndServeTLS so
|
||
|
// dead TCP connections (e.g. closing laptop mid-download) eventually
|
||
|
// go away.
|
||
|
//
|
||
|
// This is here because it is not exposed in the stdlib and
|
||
|
// we'd prefer to have a hold of the http.Server's net.Listener so we can close it
|
||
|
// on shutdown.
|
||
|
//
|
||
|
// Taken from here: https://golang.org/src/net/http/server.go?s=63121:63175#L2120
|
||
|
type TCPKeepAliveListener struct {
|
||
|
*net.TCPListener
|
||
|
}
|
||
|
|
||
|
// Accept accepts the next incoming call and returns the new
|
||
|
// connection. KeepAlivePeriod is set properly.
|
||
|
func (ln TCPKeepAliveListener) Accept() (c net.Conn, err error) {
|
||
|
tc, err := ln.AcceptTCP()
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
err = tc.SetKeepAlive(true)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
err = tc.SetKeepAlivePeriod(3 * time.Minute)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
return tc, nil
|
||
|
}
|