Add support unix socket for api module

This commit is contained in:
Alex X
2023-11-12 17:25:14 +03:00
parent 5d3953a948
commit 28830a697d

View File

@@ -10,6 +10,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"syscall"
"github.com/AlexxIT/go2rtc/internal/app" "github.com/AlexxIT/go2rtc/internal/app"
"github.com/AlexxIT/go2rtc/pkg/shell" "github.com/AlexxIT/go2rtc/pkg/shell"
@@ -19,15 +20,16 @@ import (
func Init() { func Init() {
var cfg struct { var cfg struct {
Mod struct { Mod struct {
Listen string `yaml:"listen"` Listen string `yaml:"listen"`
Username string `yaml:"username"` Username string `yaml:"username"`
Password string `yaml:"password"` Password string `yaml:"password"`
BasePath string `yaml:"base_path"` BasePath string `yaml:"base_path"`
StaticDir string `yaml:"static_dir"` StaticDir string `yaml:"static_dir"`
Origin string `yaml:"origin"` Origin string `yaml:"origin"`
TLSListen string `yaml:"tls_listen"` TLSListen string `yaml:"tls_listen"`
TLSCert string `yaml:"tls_cert"` TLSCert string `yaml:"tls_cert"`
TLSKey string `yaml:"tls_key"` TLSKey string `yaml:"tls_key"`
UnixListen string `yaml:"unix_listen"`
} `yaml:"api"` } `yaml:"api"`
} }
@@ -37,7 +39,7 @@ func Init() {
// load config from YAML // load config from YAML
app.LoadConfig(&cfg) app.LoadConfig(&cfg)
if cfg.Mod.Listen == "" { if cfg.Mod.Listen == "" && cfg.Mod.UnixListen == "" && cfg.Mod.TLSListen == "" {
return return
} }
@@ -51,16 +53,6 @@ func Init() {
HandleFunc("api/exit", exitHandler) HandleFunc("api/exit", exitHandler)
HandleFunc("api/restart", restartHandler) HandleFunc("api/restart", restartHandler)
// ensure we can listen without errors
var err error
ln, err = net.Listen("tcp", cfg.Mod.Listen)
if err != nil {
log.Fatal().Err(err).Msg("[api] listen")
return
}
log.Info().Str("addr", cfg.Mod.Listen).Msg("[api] listen")
Handler = http.DefaultServeMux // 4th Handler = http.DefaultServeMux // 4th
if cfg.Mod.Origin == "*" { if cfg.Mod.Origin == "*" {
@@ -75,49 +67,65 @@ func Init() {
Handler = middlewareLog(Handler) // 1st Handler = middlewareLog(Handler) // 1st
} }
go func() { if cfg.Mod.Listen != "" {
s := http.Server{} go listen("tcp", cfg.Mod.Listen)
s.Handler = Handler }
if err = s.Serve(ln); err != nil {
log.Fatal().Err(err).Msg("[api] serve") if cfg.Mod.UnixListen != "" {
} _ = syscall.Unlink(cfg.Mod.UnixListen)
}() go listen("unix", cfg.Mod.UnixListen)
}
// Initialize the HTTPS server // Initialize the HTTPS server
if cfg.Mod.TLSListen != "" && cfg.Mod.TLSCert != "" && cfg.Mod.TLSKey != "" { if cfg.Mod.TLSListen != "" && cfg.Mod.TLSCert != "" && cfg.Mod.TLSKey != "" {
var cert tls.Certificate go tlsListen("tcp", cfg.Mod.TLSListen, cfg.Mod.TLSCert, cfg.Mod.TLSKey)
if strings.IndexByte(cfg.Mod.TLSCert, '\n') < 0 && strings.IndexByte(cfg.Mod.TLSKey, '\n') < 0 { }
// check if file path }
cert, err = tls.LoadX509KeyPair(cfg.Mod.TLSCert, cfg.Mod.TLSKey)
} else {
// if text file content
cert, err = tls.X509KeyPair([]byte(cfg.Mod.TLSCert), []byte(cfg.Mod.TLSKey))
}
if err != nil {
log.Error().Err(err).Caller().Send()
return
}
tlsListener, err := net.Listen("tcp", cfg.Mod.TLSListen) func listen(network, address string) {
if err != nil { ln, err := net.Listen(network, address)
log.Fatal().Err(err).Caller().Send() if err != nil {
return log.Error().Err(err).Msg("[api] listen")
} return
}
log.Info().Str("addr", cfg.Mod.TLSListen).Msg("[api] tls listen") log.Info().Str("addr", address).Msg("[api] listen")
tlsServer := &http.Server{ server := http.Server{Handler: Handler}
Handler: Handler, if err = server.Serve(ln); err != nil {
TLSConfig: &tls.Config{ log.Fatal().Err(err).Msg("[api] serve")
Certificates: []tls.Certificate{cert}, }
}, }
}
go func() { func tlsListen(network, address, certFile, keyFile string) {
if err := tlsServer.ServeTLS(tlsListener, "", ""); err != nil { var cert tls.Certificate
log.Fatal().Err(err).Msg("[api] tls serve") var err error
} if strings.IndexByte(certFile, '\n') < 0 && strings.IndexByte(keyFile, '\n') < 0 {
}() // check if file path
cert, err = tls.LoadX509KeyPair(certFile, keyFile)
} else {
// if text file content
cert, err = tls.X509KeyPair([]byte(certFile), []byte(keyFile))
}
if err != nil {
log.Error().Err(err).Caller().Send()
return
}
ln, err := net.Listen(network, address)
if err != nil {
log.Error().Err(err).Msg("[api] tls listen")
return
}
log.Info().Str("addr", address).Msg("[api] tls listen")
server := &http.Server{
Handler: Handler,
TLSConfig: &tls.Config{Certificates: []tls.Certificate{cert}},
}
if err = server.ServeTLS(ln, "", ""); err != nil {
log.Fatal().Err(err).Msg("[api] tls serve")
} }
} }
@@ -187,7 +195,7 @@ func middlewareLog(next http.Handler) http.Handler {
func middlewareAuth(username, password string, next http.Handler) http.Handler { func middlewareAuth(username, password string, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.RemoteAddr, "127.") && !strings.HasPrefix(r.RemoteAddr, "[::1]") { if !strings.HasPrefix(r.RemoteAddr, "127.") && !strings.HasPrefix(r.RemoteAddr, "[::1]") && r.RemoteAddr != "@" {
user, pass, ok := r.BasicAuth() user, pass, ok := r.BasicAuth()
if !ok || user != username || pass != password { if !ok || user != username || pass != password {
w.Header().Set("Www-Authenticate", `Basic realm="go2rtc"`) w.Header().Set("Www-Authenticate", `Basic realm="go2rtc"`)