MakyuuIchaival/httputils/server.go
2022-01-18 19:10:57 +01:00

127 lines
2.7 KiB
Go

package httputils
import (
"crypto/tls"
"git.gammaspectra.live/S.O.N.G/MakyuuIchaival/tlsutils"
"github.com/dgrr/http2"
"github.com/lucas-clemente/quic-go/http3"
"github.com/valyala/fasthttp"
"log"
"net"
"net/http"
"sync"
"time"
)
type Server struct {
ListenAddress string
TLSConfig tlsutils.Configuration
EnableHTTP2 bool
EnableHTTP3 bool
Debug bool
Handler RequestHandler
extraHeadersMutex sync.RWMutex
extraHeaders map[string]string
}
type RequestHandler func(ctx *RequestContext)
func (server *Server) Serve() {
var wg sync.WaitGroup
defer wg.Wait()
if server.EnableHTTP2 {
server.TLSConfig.Config.NextProtos = []string{
"h2",
"http/1.1",
}
} else {
server.AddExtraHeader("Connection", "close")
}
wg.Add(1)
go func(wg *sync.WaitGroup) {
defer wg.Done()
s := &fasthttp.Server{
ReadTimeout: 5 * time.Second,
IdleTimeout: 15 * time.Second,
Handler: func(ctx *fasthttp.RequestCtx) {
context := NewRequestContextFromFastHttp(server, ctx)
server.Handler(&context)
},
NoDefaultServerHeader: true,
NoDefaultDate: true,
DisableKeepalive: !server.EnableHTTP2,
TCPKeepalive: server.EnableHTTP2,
TLSConfig: server.TLSConfig.Config,
}
if server.EnableHTTP2 {
http2.ConfigureServer(s, http2.ServerConfig{
Debug: server.Debug,
})
}
log.Printf("[Server] Serving TCP on %s", server.ListenAddress)
ln, err := net.Listen("tcp", server.ListenAddress)
if err != nil {
log.Panic(err)
}
defer ln.Close()
err = s.Serve(tls.NewListener(ln, s.TLSConfig.Clone()))
if err != nil {
log.Panic(err)
}
}(&wg)
if server.EnableHTTP3 {
wg.Add(1)
go func(wg *sync.WaitGroup) {
defer wg.Done()
s := &http3.Server{
Server: &http.Server{
Addr: server.ListenAddress,
TLSConfig: server.TLSConfig.QUICConfig,
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
context := NewRequestContextFromHttp(server, w, r)
if server.Debug {
log.Print("Received HTTP/3 request")
}
server.Handler(&context)
}),
},
}
h := http.Header{}
s.SetQuicHeaders(h)
server.AddExtraHeader("Alt-Svc", h.Get("Alt-Svc"))
log.Printf("[Server] Serving UDP on %s", server.ListenAddress)
err := s.ListenAndServe()
if err != nil {
log.Panic(err)
}
}(&wg)
}
}
func (server *Server) GetExtraHeaders() map[string]string {
server.extraHeadersMutex.RLock()
r := make(map[string]string)
for key, value := range server.extraHeaders {
r[key] = value
}
server.extraHeadersMutex.RUnlock()
return r
}
func (server *Server) AddExtraHeader(key, value string) {
server.extraHeadersMutex.Lock()
server.extraHeaders[key] = value
server.extraHeadersMutex.Unlock()
}