From 2751c4b8dec081a3e41c1d806170c3eed13231bf Mon Sep 17 00:00:00 2001 From: op69qs <46735012+op69qs@users.noreply.github.com> Date: Tue, 27 Oct 2020 13:29:42 +0800 Subject: [PATCH] Add server bind option (#190) * add Server.path and Server.bindAddress two options to special http server handle path and Bind Address. * Update server.go Co-authored-by: op69qs --- README.md | 4 ++++ cmd/podsync/server.go | 13 +++++++++---- pkg/config/config.go | 16 +++++++++++++++- pkg/config/config_test.go | 25 +++++++++++++++++++++++++ pkg/model/defaults.go | 1 + 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c88fe22..6774d26 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,10 @@ Here is an example how configuration might look like: ```toml [server] port = 8080 +# Bind a specific IP addresses for server ,"*": bind all IP addresses which is default option, localhost or 127.0.0.1 bind a single IPv4 address +bind_address = "172.20.10.2" +# Specify path for reverse proxy and only [A-Za-z0-9] +path = "test" data_dir = "/app/data" # Don't change if you run podsync via docker # Tokens from `Access tokens` section diff --git a/cmd/podsync/server.go b/cmd/podsync/server.go index 8d20bd0..5ab4fc5 100644 --- a/cmd/podsync/server.go +++ b/cmd/podsync/server.go @@ -18,14 +18,19 @@ func NewServer(cfg *config.Config) *Server { if port == 0 { port = 8080 } - + bindAddress := cfg.Server.BindAddress + if bindAddress == "*" { + bindAddress = "" + } srv := Server{} - srv.Addr = fmt.Sprintf(":%d", port) - log.Debugf("using address: %s", srv.Addr) + srv.Addr = fmt.Sprintf("%s:%d", bindAddress, port) + log.Debugf("using address: %s:%s", bindAddress, srv.Addr) fs := http.FileServer(http.Dir(cfg.Server.DataDir)) - http.Handle("/", fs) + path := cfg.Server.Path + http.Handle(fmt.Sprintf("/%s", path), fs) + log.Debugf("handle path: /%s", path) return &srv } diff --git a/pkg/config/config.go b/pkg/config/config.go index a01e198..9052a41 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "path/filepath" + "regexp" "github.com/hashicorp/go-multierror" "github.com/naoina/toml" @@ -71,6 +72,12 @@ type Server struct { Hostname string `toml:"hostname"` // Port is a server port to listen to Port int `toml:"port"` + // Bind a specific IP addresses for server + // "*": bind all IP addresses which is default option + // localhost or 127.0.0.1 bind a single IPv4 address + BindAddress string `toml:"bind_address"` + // Specify path for reverse proxy and only [A-Za-z0-9] + Path string `toml:"path"` // DataDir is a path to a directory to keep XML feeds and downloaded episodes, // that will be available to user via web server for download. DataDir string `toml:"data_dir"` @@ -163,8 +170,15 @@ func (c *Config) validate() error { result = multierror.Append(result, errors.New("data directory is required")) } + if c.Server.Path != "" { + var pathReg = regexp.MustCompile(model.PathRegex) + if !pathReg.MatchString(c.Server.Path) { + result = multierror.Append(result, errors.Errorf("Server handle path must be match %s or empty", model.PathRegex)) + } + } + if len(c.Feeds) == 0 { - result = multierror.Append(result, errors.New("at least one feed must be speficied")) + result = multierror.Append(result, errors.New("at least one feed must be specified")) } for id, feed := range c.Feeds { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 84cd3fa..f71a630 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -135,6 +135,31 @@ data_dir = "/data" assert.EqualValues(t, feed.Format, "video") } +func TestHttpServerListenAddress(t *testing.T) { + const file = ` +[server] +bind_address = "172.20.10.2" +port = 8080 +path = "test" +data_dir = "/data" + +[feeds] + [feeds.A] + url = "https://youtube.com/watch?v=ygIUF678y40" + +[database] + badger = { truncate = true, file_io = true } +` + path := setup(t, file) + defer os.Remove(path) + + config, err := LoadConfig(path) + assert.NoError(t, err) + require.NotNil(t, config) + require.NotNil(t, config.Server.BindAddress) + require.NotNil(t, config.Server.Path) +} + func TestDefaultHostname(t *testing.T) { cfg := Config{ Server: Server{}, diff --git a/pkg/model/defaults.go b/pkg/model/defaults.go index cd9fae9..5fefc5a 100644 --- a/pkg/model/defaults.go +++ b/pkg/model/defaults.go @@ -12,4 +12,5 @@ const ( DefaultLogMaxSize = 50 // megabytes DefaultLogMaxAge = 30 // days DefaultLogMaxBackups = 7 + PathRegex = `^[A-Za-z0-9]+$` )