add base class to all HTTP servers (#1809)

This commit is contained in:
Alessandro Ros 2023-05-16 20:12:45 +02:00 committed by GitHub
parent 9c79197f36
commit adf94092a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 145 additions and 136 deletions

View File

@ -1,15 +1,11 @@
package core
import (
"context"
"encoding/json"
"log"
"net"
"net/http"
"reflect"
"strconv"
"sync"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
@ -169,8 +165,7 @@ type api struct {
webRTCManager apiWebRTCManager
parent apiParent
ln net.Listener
httpServer *http.Server
httpServer *httpServer
mutex sync.Mutex
}
@ -187,11 +182,6 @@ func newAPI(
webRTCManager apiWebRTCManager,
parent apiParent,
) (*api, error) {
ln, err := net.Listen(restrictNetwork("tcp", address))
if err != nil {
return nil, err
}
a := &api{
conf: conf,
pathManager: pathManager,
@ -202,7 +192,6 @@ func newAPI(
hlsManager: hlsManager,
webRTCManager: webRTCManager,
parent: parent,
ln: ln,
}
router := gin.New()
@ -251,14 +240,18 @@ func newAPI(
group.POST("/v1/webrtcsessions/kick/:id", a.onWebRTCSessionsKick)
}
a.httpServer = &http.Server{
Handler: router,
ReadHeaderTimeout: time.Duration(readTimeout),
ErrorLog: log.New(&nilWriter{}, "", 0),
var err error
a.httpServer, err = newHTTPServer(
address,
readTimeout,
"",
"",
router,
)
if err != nil {
return nil, err
}
go a.httpServer.Serve(ln)
a.Log(logger.Info, "listener opened on "+address)
return a, nil
@ -266,8 +259,7 @@ func newAPI(
func (a *api) close() {
a.Log(logger.Info, "listener is closing")
a.httpServer.Shutdown(context.Background())
a.ln.Close() // in case Shutdown() is called before Serve()
a.httpServer.close()
}
func (a *api) Log(level logger.Level, format string, args ...interface{}) {

View File

@ -1,15 +1,12 @@
package core
import (
"context"
"crypto/tls"
_ "embed"
"log"
"fmt"
"net"
"net/http"
gopath "path"
"strings"
"time"
"github.com/gin-gonic/gin"
@ -30,8 +27,7 @@ type hlsHTTPServer struct {
pathManager *pathManager
parent hlsHTTPServerParent
ln net.Listener
inner *http.Server
inner *httpServer
}
func newHLSHTTPServer( //nolint:dupl
@ -45,29 +41,19 @@ func newHLSHTTPServer( //nolint:dupl
pathManager *pathManager,
parent hlsHTTPServerParent,
) (*hlsHTTPServer, error) {
ln, err := net.Listen(restrictNetwork("tcp", address))
if err != nil {
return nil, err
}
var tlsConfig *tls.Config
if encryption {
crt, err := tls.LoadX509KeyPair(serverCert, serverKey)
if err != nil {
ln.Close()
return nil, err
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{crt},
if serverCert == "" {
return nil, fmt.Errorf("server cert is missing")
}
} else {
serverKey = ""
serverCert = ""
}
s := &hlsHTTPServer{
allowOrigin: allowOrigin,
pathManager: pathManager,
parent: parent,
ln: ln,
}
router := gin.New()
@ -75,17 +61,16 @@ func newHLSHTTPServer( //nolint:dupl
router.NoRoute(httpLoggerMiddleware(s), httpServerHeaderMiddleware, s.onRequest)
s.inner = &http.Server{
Handler: router,
TLSConfig: tlsConfig,
ReadHeaderTimeout: time.Duration(readTimeout),
ErrorLog: log.New(&nilWriter{}, "", 0),
}
if tlsConfig != nil {
go s.inner.ServeTLS(s.ln, "", "")
} else {
go s.inner.Serve(s.ln)
var err error
s.inner, err = newHTTPServer(
address,
readTimeout,
serverCert,
serverKey,
router,
)
if err != nil {
return nil, err
}
return s, nil
@ -96,8 +81,7 @@ func (s *hlsHTTPServer) Log(level logger.Level, format string, args ...interface
}
func (s *hlsHTTPServer) close() {
s.inner.Shutdown(context.Background())
s.ln.Close() // in case Shutdown() is called before Serve()
s.inner.close()
}
func (s *hlsHTTPServer) onRequest(ctx *gin.Context) {

View File

@ -10,12 +10,6 @@ import (
"github.com/bluenviron/mediamtx/internal/logger"
)
type nilWriter struct{}
func (nilWriter) Write(p []byte) (int, error) {
return len(p), nil
}
type hlsManagerAPIMuxersListItem struct {
Path string `json:"path"`
Created time.Time `json:"created"`

View File

@ -0,0 +1,72 @@
package core
import (
"context"
"crypto/tls"
"log"
"net"
"net/http"
"time"
"github.com/bluenviron/mediamtx/internal/conf"
)
type nilWriter struct{}
func (nilWriter) Write(p []byte) (int, error) {
return len(p), nil
}
type httpServer struct {
ln net.Listener
inner *http.Server
}
func newHTTPServer(
address string,
readTimeout conf.StringDuration,
serverCert string,
serverKey string,
handler http.Handler,
) (*httpServer, error) {
ln, err := net.Listen(restrictNetwork("tcp", address))
if err != nil {
return nil, err
}
var tlsConfig *tls.Config
if serverCert != "" {
crt, err := tls.LoadX509KeyPair(serverCert, serverKey)
if err != nil {
ln.Close()
return nil, err
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{crt},
}
}
s := &httpServer{
ln: ln,
inner: &http.Server{
Handler: handler,
TLSConfig: tlsConfig,
ReadHeaderTimeout: time.Duration(readTimeout),
ErrorLog: log.New(&nilWriter{}, "", 0),
},
}
if tlsConfig != nil {
go s.inner.ServeTLS(s.ln, "", "")
} else {
go s.inner.Serve(s.ln)
}
return s, nil
}
func (s *httpServer) close() {
s.inner.Shutdown(context.Background())
s.ln.Close() // in case Shutdown() is called before Serve()
}

View File

@ -1,14 +1,10 @@
package core
import (
"context"
"io"
"log"
"net"
"net/http"
"strconv"
"sync"
"time"
"github.com/gin-gonic/gin"
@ -27,8 +23,7 @@ type metricsParent interface {
type metrics struct {
parent metricsParent
ln net.Listener
httpServer *http.Server
httpServer *httpServer
mutex sync.Mutex
pathManager apiPathManager
rtspServer apiRTSPServer
@ -43,14 +38,8 @@ func newMetrics(
readTimeout conf.StringDuration,
parent metricsParent,
) (*metrics, error) {
ln, err := net.Listen(restrictNetwork("tcp", address))
if err != nil {
return nil, err
}
m := &metrics{
parent: parent,
ln: ln,
}
router := gin.New()
@ -60,23 +49,26 @@ func newMetrics(
router.NoRoute(mwLog)
router.GET("/metrics", mwLog, m.onMetrics)
m.httpServer = &http.Server{
Handler: router,
ReadHeaderTimeout: time.Duration(readTimeout),
ErrorLog: log.New(&nilWriter{}, "", 0),
var err error
m.httpServer, err = newHTTPServer(
address,
readTimeout,
"",
"",
router,
)
if err != nil {
return nil, err
}
m.Log(logger.Info, "listener opened on "+address)
go m.httpServer.Serve(m.ln)
return m, nil
}
func (m *metrics) close() {
m.Log(logger.Info, "listener is closing")
m.httpServer.Shutdown(context.Background())
m.ln.Close() // in case Shutdown() is called before Serve()
m.httpServer.close()
}
func (m *metrics) Log(level logger.Level, format string, args ...interface{}) {

View File

@ -1,11 +1,7 @@
package core
import (
"context"
"log"
"net"
"net/http"
"time"
// start pprof
_ "net/http/pprof"
@ -21,8 +17,7 @@ type pprofParent interface {
type pprof struct {
parent pprofParent
ln net.Listener
httpServer *http.Server
httpServer *httpServer
}
func newPPROF(
@ -30,33 +25,30 @@ func newPPROF(
readTimeout conf.StringDuration,
parent pprofParent,
) (*pprof, error) {
ln, err := net.Listen(restrictNetwork("tcp", address))
pp := &pprof{
parent: parent,
}
var err error
pp.httpServer, err = newHTTPServer(
address,
readTimeout,
"",
"",
http.DefaultServeMux,
)
if err != nil {
return nil, err
}
pp := &pprof{
parent: parent,
ln: ln,
}
pp.httpServer = &http.Server{
Handler: http.DefaultServeMux,
ReadHeaderTimeout: time.Duration(readTimeout),
ErrorLog: log.New(&nilWriter{}, "", 0),
}
pp.Log(logger.Info, "listener opened on "+address)
go pp.httpServer.Serve(pp.ln)
return pp, nil
}
func (pp *pprof) close() {
pp.Log(logger.Info, "listener is closing")
pp.httpServer.Shutdown(context.Background())
pp.ln.Close() // in case Shutdown() is called before Serve()
pp.httpServer.close()
}
func (pp *pprof) Log(level logger.Level, format string, args ...interface{}) {

View File

@ -1,17 +1,13 @@
package core
import (
"context"
"crypto/tls"
_ "embed"
"fmt"
"io"
"log"
"net"
"net/http"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
@ -118,8 +114,7 @@ type webRTCHTTPServer struct {
pathManager *pathManager
parent webRTCHTTPServerParent
ln net.Listener
inner *http.Server
inner *httpServer
}
func newWebRTCHTTPServer( //nolint:dupl
@ -133,46 +128,35 @@ func newWebRTCHTTPServer( //nolint:dupl
pathManager *pathManager,
parent webRTCHTTPServerParent,
) (*webRTCHTTPServer, error) {
ln, err := net.Listen(restrictNetwork("tcp", address))
if err != nil {
return nil, err
}
var tlsConfig *tls.Config
if encryption {
crt, err := tls.LoadX509KeyPair(serverCert, serverKey)
if err != nil {
ln.Close()
return nil, err
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{crt},
if serverCert == "" {
return nil, fmt.Errorf("server cert is missing")
}
} else {
serverKey = ""
serverCert = ""
}
s := &webRTCHTTPServer{
allowOrigin: allowOrigin,
pathManager: pathManager,
parent: parent,
ln: ln,
}
router := gin.New()
httpSetTrustedProxies(router, trustedProxies)
router.NoRoute(httpLoggerMiddleware(s), httpServerHeaderMiddleware, s.onRequest)
s.inner = &http.Server{
Handler: router,
TLSConfig: tlsConfig,
ReadHeaderTimeout: time.Duration(readTimeout),
ErrorLog: log.New(&nilWriter{}, "", 0),
}
if tlsConfig != nil {
go s.inner.ServeTLS(s.ln, "", "")
} else {
go s.inner.Serve(s.ln)
var err error
s.inner, err = newHTTPServer(
address,
readTimeout,
serverCert,
serverKey,
router,
)
if err != nil {
return nil, err
}
return s, nil
@ -183,8 +167,7 @@ func (s *webRTCHTTPServer) Log(level logger.Level, format string, args ...interf
}
func (s *webRTCHTTPServer) close() {
s.inner.Shutdown(context.Background())
s.ln.Close() // in case Shutdown() is called before Serve()
s.inner.close()
}
func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {