Add support CORS for API
This commit is contained in:
@@ -313,9 +313,10 @@ The HTTP API is the main part for interacting with the application. Default addr
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
api:
|
api:
|
||||||
listen: ":1984" # HTTP API port ("" - disabled)
|
listen: ":1984" # HTTP API port ("" - disabled)
|
||||||
base_path: "" # API prefix for serve on suburl
|
base_path: "/rtc" # API prefix for serve on suburl (/api => /rtc/api)
|
||||||
static_dir: "" # folder for static files (custom web interface)
|
static_dir: "www" # folder for static files (custom web interface)
|
||||||
|
origin: "*" # allow CORS requests (only * supported)
|
||||||
```
|
```
|
||||||
|
|
||||||
**PS. go2rtc** doesn't provide HTTPS or password protection. Use [Nginx](https://nginx.org/) or [Ngrok](#module-ngrok) or [Home Assistant Add-on](#go2rtc-home-assistant-add-on) for this tasks.
|
**PS. go2rtc** doesn't provide HTTPS or password protection. Use [Nginx](https://nginx.org/) or [Ngrok](#module-ngrok) or [Home Assistant Add-on](#go2rtc-home-assistant-add-on) for this tasks.
|
||||||
|
|||||||
+29
-11
@@ -17,6 +17,7 @@ func Init() {
|
|||||||
Listen string `yaml:"listen"`
|
Listen string `yaml:"listen"`
|
||||||
BasePath string `yaml:"base_path"`
|
BasePath string `yaml:"base_path"`
|
||||||
StaticDir string `yaml:"static_dir"`
|
StaticDir string `yaml:"static_dir"`
|
||||||
|
Origin string `yaml:"origin"`
|
||||||
} `yaml:"api"`
|
} `yaml:"api"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ func Init() {
|
|||||||
log = app.GetLogger("api")
|
log = app.GetLogger("api")
|
||||||
|
|
||||||
initStatic(cfg.Mod.StaticDir)
|
initStatic(cfg.Mod.StaticDir)
|
||||||
initWS()
|
initWS(cfg.Mod.Origin)
|
||||||
|
|
||||||
HandleFunc("api/streams", streamsHandler)
|
HandleFunc("api/streams", streamsHandler)
|
||||||
HandleFunc("api/ws", apiWS)
|
HandleFunc("api/ws", apiWS)
|
||||||
@@ -48,16 +49,18 @@ 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{}
|
||||||
|
s.Handler = http.DefaultServeMux
|
||||||
|
|
||||||
|
if log.Trace().Enabled() {
|
||||||
|
s.Handler = middlewareLog(s.Handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Mod.Origin == "*" {
|
||||||
|
s.Handler = middlewareCORS(s.Handler)
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
s := http.Server{}
|
|
||||||
|
|
||||||
if log.Trace().Enabled() {
|
|
||||||
s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
log.Trace().Stringer("url", r.URL).Msgf("[api] %s", r.Method)
|
|
||||||
http.DefaultServeMux.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
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")
|
||||||
}
|
}
|
||||||
@@ -83,10 +86,25 @@ var basePath string
|
|||||||
var log zerolog.Logger
|
var log zerolog.Logger
|
||||||
var wsHandlers = make(map[string]WSHandler)
|
var wsHandlers = make(map[string]WSHandler)
|
||||||
|
|
||||||
|
func middlewareLog(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Trace().Msgf("[api] %s %s", r.Method, r.URL)
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func middlewareCORS(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func streamsHandler(w http.ResponseWriter, r *http.Request) {
|
func streamsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
src := r.URL.Query().Get("src")
|
src := r.URL.Query().Get("src")
|
||||||
name := r.URL.Query().Get("name")
|
name := r.URL.Query().Get("name")
|
||||||
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = src
|
name = src
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-20
@@ -4,35 +4,19 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initWS() {
|
func initWS(origin string) {
|
||||||
wsUp = &websocket.Upgrader{
|
wsUp = &websocket.Upgrader{
|
||||||
ReadBufferSize: 1024,
|
ReadBufferSize: 1024,
|
||||||
WriteBufferSize: 512000,
|
WriteBufferSize: 512000,
|
||||||
}
|
}
|
||||||
wsUp.CheckOrigin = func(r *http.Request) bool {
|
|
||||||
origin := r.Header["Origin"]
|
if origin == "*" {
|
||||||
if len(origin) == 0 {
|
wsUp.CheckOrigin = func(r *http.Request) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
o, err := url.Parse(origin[0])
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if o.Host == r.Host {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
log.Trace().Msgf("[api.ws] origin: %s, host: %s", o.Host, r.Host)
|
|
||||||
// some users change Nginx external port using Docker port
|
|
||||||
// so origin will be with a port and host without
|
|
||||||
if i := strings.IndexByte(o.Host, ':'); i > 0 {
|
|
||||||
return o.Host[:i] == r.Host
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user