- Uses certificate and key files provided by admin in config - Let's Encrypt integration planned, but not even close to working - Initial HTTP3 Support added
This commit is contained in:
parent
68d7a5e8c3
commit
9151bfb3be
6 changed files with 250 additions and 42 deletions
40
web/public/middleware/httpUpgrade.go
Normal file
40
web/public/middleware/httpUpgrade.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package webmiddleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.mstar.dev/mstar/linstrom/config"
|
||||
)
|
||||
|
||||
func AddUpgradeHeader(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.ProtoMajor {
|
||||
case 1:
|
||||
// Always offer upgrade to http2
|
||||
headerText := fmt.Sprintf(
|
||||
"h2=\":%d\"; ma=3600",
|
||||
config.GlobalConfig.General.GetFinalPublicPort(),
|
||||
)
|
||||
// Offer upgrade to http3 if enabled
|
||||
if config.GlobalConfig.Experimental.Http3Support && config.GlobalConfig.SSL.HandleSSL {
|
||||
headerText = fmt.Sprintf(
|
||||
"h3=\":%d\"; ma=3600, %s",
|
||||
config.GlobalConfig.General.GetFinalPublicPort(),
|
||||
headerText,
|
||||
)
|
||||
}
|
||||
w.Header().Add("Alt-Svc", headerText)
|
||||
case 2:
|
||||
// Offer upgrade to http3 if enabled
|
||||
if config.GlobalConfig.Experimental.Http3Support && config.GlobalConfig.SSL.HandleSSL {
|
||||
headerText := fmt.Sprintf(
|
||||
"h3=\":%d\"; ma=3600",
|
||||
config.GlobalConfig.General.GetFinalPublicPort(),
|
||||
)
|
||||
w.Header().Add("Alt-Svc", headerText)
|
||||
}
|
||||
}
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
|
@ -32,13 +32,18 @@ import (
|
|||
"net/http"
|
||||
|
||||
webutils "git.mstar.dev/mstar/goutils/http"
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"git.mstar.dev/mstar/linstrom/auth-new"
|
||||
"git.mstar.dev/mstar/linstrom/config"
|
||||
"git.mstar.dev/mstar/linstrom/web/public/api"
|
||||
webmiddleware "git.mstar.dev/mstar/linstrom/web/public/middleware"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
server *http.Server
|
||||
server *http.Server
|
||||
quicServer *http3.Server
|
||||
}
|
||||
|
||||
func New(addr string, duckImg *string, duckFs fs.FS) *Server {
|
||||
|
@ -51,28 +56,92 @@ func New(addr string, duckImg *string, duckFs fs.FS) *Server {
|
|||
handler.HandleFunc("GET /errors/{name}", errorTypeHandler)
|
||||
handler.HandleFunc("GET /default-image", buildServeDefaultImage(duckImg, duckFs))
|
||||
handler.HandleFunc("GET /default-image.webp", buildServeDefaultImage(duckImg, duckFs))
|
||||
server := http.Server{
|
||||
Handler: webutils.ChainMiddlewares(
|
||||
handler,
|
||||
webutils.BuildLoggingMiddleware(
|
||||
true,
|
||||
[]string{"/assets"},
|
||||
map[string]string{"server": "public"},
|
||||
),
|
||||
webmiddleware.AppendFullPathMiddleware,
|
||||
webmiddleware.TraceRequestInfoMiddleware,
|
||||
rootHandler := webutils.ChainMiddlewares(
|
||||
handler,
|
||||
webutils.BuildLoggingMiddleware(
|
||||
true,
|
||||
[]string{"/assets"},
|
||||
map[string]string{"server": "public"},
|
||||
),
|
||||
Addr: addr,
|
||||
webmiddleware.AppendFullPathMiddleware,
|
||||
webmiddleware.TraceRequestInfoMiddleware,
|
||||
webmiddleware.AddUpgradeHeader,
|
||||
)
|
||||
server := http.Server{
|
||||
Handler: rootHandler,
|
||||
Addr: addr,
|
||||
}
|
||||
return &Server{&server}
|
||||
quicServer := http3.Server{
|
||||
Handler: rootHandler,
|
||||
Addr: addr,
|
||||
}
|
||||
if config.GlobalConfig.General.PublicPort != nil {
|
||||
quicServer.Port = *config.GlobalConfig.General.PublicPort
|
||||
}
|
||||
return &Server{server: &server, quicServer: &quicServer}
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
return s.server.ListenAndServe()
|
||||
if config.GlobalConfig.SSL.HandleSSL {
|
||||
certFile, keyFile, err := auth.TlsFromConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if config.GlobalConfig.Experimental.Http3Support {
|
||||
errChan := make(chan error, 2)
|
||||
go func() {
|
||||
errChan <- s.server.ListenAndServeTLS(certFile, keyFile)
|
||||
}()
|
||||
go func() {
|
||||
errChan <- s.quicServer.ListenAndServeTLS(certFile, keyFile)
|
||||
}()
|
||||
|
||||
err := <-errChan
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
// Always gets two values back on the channel since both servers are running
|
||||
err = <-errChan
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return s.server.ListenAndServeTLS(certFile, keyFile)
|
||||
}
|
||||
} else {
|
||||
// But refuse http3 support here, since it doesn't work without tls
|
||||
return s.server.ListenAndServe()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Stop() error {
|
||||
return s.server.Shutdown(context.Background())
|
||||
if config.GlobalConfig.SSL.HandleSSL && config.GlobalConfig.Experimental.Http3Support {
|
||||
errChan := make(chan error, 2)
|
||||
go func() {
|
||||
log.Debug().Msg("Stopping tcp server")
|
||||
errChan <- s.server.Shutdown(context.Background())
|
||||
log.Debug().Msg("Tcp server stopped")
|
||||
}()
|
||||
go func() {
|
||||
log.Debug().Msg("Stopping udp server")
|
||||
errChan <- s.quicServer.Shutdown(context.Background())
|
||||
log.Debug().Msg("Udp server stopped")
|
||||
}()
|
||||
|
||||
err := <-errChan
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
// Always gets two values back on the channel since both servers are running
|
||||
err = <-errChan
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return s.server.Shutdown(context.Background())
|
||||
}
|
||||
}
|
||||
|
||||
func buildServeDefaultImage(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue