Skip to content

Commit

Permalink
add base class to all HTTP servers (#1809)
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 authored May 16, 2023
1 parent 9c79197 commit adf9409
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 134 deletions.
32 changes: 12 additions & 20 deletions internal/core/api.go
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -169,8 +165,7 @@ type api struct {
webRTCManager apiWebRTCManager
parent apiParent

ln net.Listener
httpServer *http.Server
httpServer *httpServer
mutex sync.Mutex
}

Expand All @@ -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,
Expand All @@ -202,7 +192,6 @@ func newAPI(
hlsManager: hlsManager,
webRTCManager: webRTCManager,
parent: parent,
ln: ln,
}

router := gin.New()
Expand Down Expand Up @@ -251,23 +240,26 @@ 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
}

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{}) {
Expand Down
52 changes: 18 additions & 34 deletions internal/core/hls_http_server.go
Original file line number Diff line number Diff line change
@@ -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"

Expand All @@ -30,8 +27,7 @@ type hlsHTTPServer struct {
pathManager *pathManager
parent hlsHTTPServerParent

ln net.Listener
inner *http.Server
inner *httpServer
}

func newHLSHTTPServer( //nolint:dupl
Expand All @@ -45,47 +41,36 @@ 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()
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
Expand All @@ -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) {
Expand Down
6 changes: 0 additions & 6 deletions internal/core/hls_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
72 changes: 72 additions & 0 deletions internal/core/http_server.go
Original file line number Diff line number Diff line change
@@ -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()
}
32 changes: 12 additions & 20 deletions internal/core/metrics.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package core

import (
"context"
"io"
"log"
"net"
"net/http"
"strconv"
"sync"
"time"

"github.com/gin-gonic/gin"

Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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{}) {
Expand Down
Loading

0 comments on commit adf9409

Please sign in to comment.