Fix listening on hassio interface

This commit is contained in:
Alexey Khit
2023-03-25 14:58:45 +03:00
parent 8bf5c85b79
commit 5c164de393
3 changed files with 80 additions and 30 deletions

View File

@@ -54,28 +54,31 @@ func Init() {
log.Info().Str("addr", cfg.Mod.Listen).Msg("[api] listen") log.Info().Str("addr", cfg.Mod.Listen).Msg("[api] listen")
s := http.Server{} Handler = http.DefaultServeMux // 4th
s.Handler = http.DefaultServeMux // 4th
if cfg.Mod.Origin == "*" { if cfg.Mod.Origin == "*" {
s.Handler = middlewareCORS(s.Handler) // 3rd Handler = middlewareCORS(Handler) // 3rd
} }
if cfg.Mod.Username != "" { if cfg.Mod.Username != "" {
s.Handler = middlewareAuth(cfg.Mod.Username, cfg.Mod.Password, s.Handler) // 2nd Handler = middlewareAuth(cfg.Mod.Username, cfg.Mod.Password, Handler) // 2nd
} }
if log.Trace().Enabled() { if log.Trace().Enabled() {
s.Handler = middlewareLog(s.Handler) // 1st Handler = middlewareLog(Handler) // 1st
} }
go func() { go func() {
s := http.Server{}
s.Handler = Handler
if err = s.Serve(listener); err != nil { if err = s.Serve(listener); err != nil {
log.Fatal().Err(err).Msg("[api] serve") log.Fatal().Err(err).Msg("[api] serve")
} }
}() }()
} }
var Handler http.Handler
// HandleFunc handle pattern with relative path: // HandleFunc handle pattern with relative path:
// - "api/streams" => "{basepath}/api/streams" // - "api/streams" => "{basepath}/api/streams"
// - "/streams" => "/streams" // - "/streams" => "/streams"

View File

@@ -6,6 +6,7 @@ import (
"github.com/AlexxIT/go2rtc/cmd/api" "github.com/AlexxIT/go2rtc/cmd/api"
"github.com/AlexxIT/go2rtc/cmd/streams" "github.com/AlexxIT/go2rtc/cmd/streams"
"github.com/AlexxIT/go2rtc/cmd/webrtc" "github.com/AlexxIT/go2rtc/cmd/webrtc"
"net"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@@ -133,6 +134,25 @@ func initAPI() {
}) })
} }
func HassioAddr() string {
ints, _ := net.Interfaces()
for _, i := range ints {
if i.Name != "hassio" {
continue
}
addrs, _ := i.Addrs()
for _, addr := range addrs {
if addr, ok := addr.(*net.IPNet); ok {
return addr.IP.String()
}
}
}
return ""
}
func rtspStream(url string) *streams.Stream { func rtspStream(url string) *streams.Stream {
if strings.HasPrefix(url, "rtsp://") { if strings.HasPrefix(url, "rtsp://") {
if i := strings.IndexByte(url[7:], '/'); i > 0 { if i := strings.IndexByte(url[7:], '/'); i > 0 {

View File

@@ -17,6 +17,9 @@ import (
func Init() { func Init() {
var conf struct { var conf struct {
API struct {
Listen string `json:"listen"`
} `yaml:"api"`
Mod struct { Mod struct {
Config string `yaml:"config"` Config string `yaml:"config"`
} `yaml:"hass"` } `yaml:"hass"`
@@ -28,35 +31,68 @@ func Init() {
initAPI() initAPI()
// support load cameras from Hass config file entries := importEntries(conf.Mod.Config)
filename := path.Join(conf.Mod.Config, ".storage/core.config_entries") if entries == nil {
b, err := os.ReadFile(filename) api.HandleFunc("api/hass", func(w http.ResponseWriter, _ *http.Request) {
if err != nil { http.Error(w, "no hass config", http.StatusNotFound)
})
return return
} }
storage := new(entries) api.HandleFunc("api/hass", func(w http.ResponseWriter, _ *http.Request) {
if err = json.Unmarshal(b, storage); err != nil {
return
}
urls := map[string]string{}
api.HandleFunc("api/hass", func(w http.ResponseWriter, r *http.Request) {
var items []api.Stream var items []api.Stream
for name, url := range urls { for name, url := range entries {
items = append(items, api.Stream{Name: name, URL: url}) items = append(items, api.Stream{Name: name, URL: url})
} }
api.ResponseStreams(w, items) api.ResponseStreams(w, items)
}) })
streams.HandleFunc("hass", func(url string) (core.Producer, error) { streams.HandleFunc("hass", func(url string) (core.Producer, error) {
if hurl := urls[url[5:]]; hurl != "" { if hurl := entries[url[5:]]; hurl != "" {
return streams.GetProducer(hurl) return streams.GetProducer(hurl)
} }
return nil, fmt.Errorf("can't get url: %s", url) return nil, fmt.Errorf("can't get url: %s", url)
}) })
// for Addon listen on hassio interface, so WebUI feature will work
if conf.API.Listen == "127.0.0.1:1984" {
if addr := HassioAddr(); addr != "" {
addr += ":1984"
go func() {
log.Info().Str("addr", addr).Msg("[hass] listen")
if err := http.ListenAndServe(addr, api.Handler); err != nil {
log.Error().Err(err).Caller().Send()
}
}()
}
}
}
func importEntries(config string) map[string]string {
// support load cameras from Hass config file
filename := path.Join(config, ".storage/core.config_entries")
b, err := os.ReadFile(filename)
if err != nil {
return nil
}
var storage struct {
Data struct {
Entries []struct {
Title string `json:"title"`
Domain string `json:"domain"`
Data json.RawMessage `json:"data"`
Options json.RawMessage `json:"options"`
} `json:"entries"`
} `json:"data"`
}
if err = json.Unmarshal(b, &storage); err != nil {
return nil
}
urls := map[string]string{}
for _, entrie := range storage.Data.Entries { for _, entrie := range storage.Data.Entries {
switch entrie.Domain { switch entrie.Domain {
case "generic": case "generic":
@@ -102,17 +138,8 @@ func Init() {
log.Info().Str("url", "hass:"+entrie.Title).Msg("[hass] load stream") log.Info().Str("url", "hass:"+entrie.Title).Msg("[hass] load stream")
//streams.Get("hass:" + entrie.Title) //streams.Get("hass:" + entrie.Title)
} }
return urls
} }
var log zerolog.Logger var log zerolog.Logger
type entries struct {
Data struct {
Entries []struct {
Title string `json:"title"`
Domain string `json:"domain"`
Data json.RawMessage `json:"data"`
Options json.RawMessage `json:"options"`
} `json:"entries"`
} `json:"data"`
}