Manager: dynamically generate allowed CORS origins
Remove the hard-coded list of allowed CORS origins, and build it dynamically from the list of "own URLs", i.e. the URLs at which the Manager expects to be available. This list of "own URLs" is constructed from the available network interfaces.
This commit is contained in:
parent
1847c5219d
commit
4ea6f99c3e
@ -6,11 +6,14 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
@ -43,6 +46,8 @@ var cliArgs struct {
|
|||||||
writeConfig bool
|
writeConfig bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const developmentWebInterfacePort = 8081
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
output := zerolog.ConsoleWriter{Out: colorable.NewColorableStdout(), TimeFormat: time.RFC3339}
|
output := zerolog.ConsoleWriter{Out: colorable.NewColorableStdout(), TimeFormat: time.RFC3339}
|
||||||
log.Logger = log.Output(output)
|
log.Logger = log.Output(output)
|
||||||
@ -83,7 +88,12 @@ func main() {
|
|||||||
_, port, _ := net.SplitHostPort(listen)
|
_, port, _ := net.SplitHostPort(listen)
|
||||||
log.Info().Str("port", port).Msg("listening")
|
log.Info().Str("port", port).Msg("listening")
|
||||||
|
|
||||||
ssdp := makeAutoDiscoverable("http", listen)
|
urls, err := own_url.AvailableURLs("http", listen)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("unable to figure out my own URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
ssdp := makeAutoDiscoverable(urls)
|
||||||
|
|
||||||
// Construct the services.
|
// Construct the services.
|
||||||
persist := openDB(*configService)
|
persist := openDB(*configService)
|
||||||
@ -96,7 +106,7 @@ func main() {
|
|||||||
|
|
||||||
webUpdater := webupdates.New()
|
webUpdater := webupdates.New()
|
||||||
flamenco := buildFlamencoAPI(configService, persist, webUpdater)
|
flamenco := buildFlamencoAPI(configService, persist, webUpdater)
|
||||||
e := buildWebService(flamenco, persist, ssdp, webUpdater)
|
e := buildWebService(flamenco, persist, ssdp, webUpdater, urls)
|
||||||
|
|
||||||
installSignalHandler(mainCtxCancel)
|
installSignalHandler(mainCtxCancel)
|
||||||
|
|
||||||
@ -150,6 +160,7 @@ func buildWebService(
|
|||||||
persist api_impl.PersistenceService,
|
persist api_impl.PersistenceService,
|
||||||
ssdp *upnp_ssdp.Server,
|
ssdp *upnp_ssdp.Server,
|
||||||
webUpdater *webupdates.BiDirComms,
|
webUpdater *webupdates.BiDirComms,
|
||||||
|
ownURLs []url.URL,
|
||||||
) *echo.Echo {
|
) *echo.Echo {
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.HideBanner = true
|
e.HideBanner = true
|
||||||
@ -175,8 +186,7 @@ func buildWebService(
|
|||||||
// e.Use(middleware.Gzip())
|
// e.Use(middleware.Gzip())
|
||||||
|
|
||||||
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
|
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
|
||||||
// Just some hard-coded URLs for now, just to get some tests going.
|
AllowOrigins: corsOrigins(ownURLs),
|
||||||
AllowOrigins: []string{"http://localhost:8080", "http://localhost:8081", "http://10.161.30.150:8081"},
|
|
||||||
|
|
||||||
// List taken from https://www.bacancytechnology.com/blog/real-time-chat-application-using-socketio-golang-vuejs/
|
// List taken from https://www.bacancytechnology.com/blog/real-time-chat-application-using-socketio-golang-vuejs/
|
||||||
AllowHeaders: []string{
|
AllowHeaders: []string{
|
||||||
@ -346,13 +356,7 @@ func installSignalHandler(cancelFunc context.CancelFunc) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeAutoDiscoverable(scheme, listen string) *upnp_ssdp.Server {
|
func makeAutoDiscoverable(urls []url.URL) *upnp_ssdp.Server {
|
||||||
urls, err := own_url.AvailableURLs("http", listen)
|
|
||||||
if err != nil {
|
|
||||||
log.Error().Err(err).Msg("unable to figure out my own URL")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ssdp, err := upnp_ssdp.NewServer(log.Logger)
|
ssdp, err := upnp_ssdp.NewServer(log.Logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("error creating UPnP/SSDP server")
|
log.Error().Err(err).Msg("error creating UPnP/SSDP server")
|
||||||
@ -362,3 +366,22 @@ func makeAutoDiscoverable(scheme, listen string) *upnp_ssdp.Server {
|
|||||||
ssdp.AddAdvertisementURLs(urls)
|
ssdp.AddAdvertisementURLs(urls)
|
||||||
return ssdp
|
return ssdp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// corsOrigins strips everything from the URL that follows the hostname:port, so
|
||||||
|
// that it's suitable for checking Origin headers of CORS OPTIONS requests.
|
||||||
|
func corsOrigins(urls []url.URL) []string {
|
||||||
|
origins := make([]string, len(urls))
|
||||||
|
|
||||||
|
// TODO: find a way to allow CORS requests during development, but not when
|
||||||
|
// running in production.
|
||||||
|
|
||||||
|
for i, url := range urls {
|
||||||
|
// Allow the `yarn run dev` webserver do cross-origin requests to this Manager.
|
||||||
|
url.Path = ""
|
||||||
|
url.Fragment = ""
|
||||||
|
url.Host = fmt.Sprintf("%s:%d", url.Hostname(), developmentWebInterfacePort)
|
||||||
|
origins[i] = url.String()
|
||||||
|
}
|
||||||
|
log.Debug().Str("origins", strings.Join(origins, " ")).Msg("accepted CORS origins")
|
||||||
|
return origins
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user