golanggohlsrtmpwebrtcmedia-serverobs-studiortcprtmp-proxyrtmp-serverrtprtsprtsp-proxyrtsp-relayrtsp-serversrtstreamingwebrtc-proxy
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.
93 lines
1.8 KiB
93 lines
1.8 KiB
// Package httpp contains HTTP utilities. |
|
package httpp |
|
|
|
import ( |
|
"context" |
|
"crypto/tls" |
|
"log" |
|
"net" |
|
"net/http" |
|
"time" |
|
|
|
"github.com/bluenviron/mediamtx/internal/logger" |
|
) |
|
|
|
type nilWriter struct{} |
|
|
|
func (nilWriter) Write(p []byte) (int, error) { |
|
return len(p), nil |
|
} |
|
|
|
// WrappedServer is a wrapper around http.Server that provides: |
|
// - net.Listener allocation and closure |
|
// - TLS allocation |
|
// - exit on panic |
|
// - logging |
|
// - server header |
|
// - filtering of invalid requests |
|
type WrappedServer struct { |
|
ln net.Listener |
|
inner *http.Server |
|
} |
|
|
|
// NewWrappedServer allocates a WrappedServer. |
|
func NewWrappedServer( |
|
network string, |
|
address string, |
|
readTimeout time.Duration, |
|
serverCert string, |
|
serverKey string, |
|
handler http.Handler, |
|
parent logger.Writer, |
|
) (*WrappedServer, error) { |
|
ln, err := net.Listen(network, 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}, |
|
} |
|
} |
|
|
|
h := handler |
|
h = &handlerFilterRequests{h} |
|
h = &handlerFilterRequests{h} |
|
h = &handlerServerHeader{h} |
|
h = &handlerLogger{h, parent} |
|
h = &handlerExitOnPanic{h} |
|
|
|
s := &WrappedServer{ |
|
ln: ln, |
|
inner: &http.Server{ |
|
Handler: h, |
|
TLSConfig: tlsConfig, |
|
ReadHeaderTimeout: 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 |
|
} |
|
|
|
// Close closes all resources and waits for all routines to return. |
|
func (s *WrappedServer) Close() { |
|
ctx, ctxCancel := context.WithCancel(context.Background()) |
|
ctxCancel() |
|
s.inner.Shutdown(ctx) |
|
s.ln.Close() // in case Shutdown() is called before Serve() |
|
}
|
|
|