From d0f8c141e1427605bc7cd238ebae12ea9d758a77 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Fri, 17 May 2019 11:48:06 +0100 Subject: [PATCH] feat: adds support for unix sockets (#729) License: MIT Signed-off-by: Henrique Dias --- cmd/config.go | 1 + cmd/config_init.go | 1 + cmd/config_set.go | 2 ++ cmd/root.go | 59 +++++++++++++++++++++++++++++++++++++------- settings/settings.go | 1 + 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/cmd/config.go b/cmd/config.go index 25903137..ce8ebdb7 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -101,6 +101,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port) fmt.Fprintf(w, "\tBase URL:\t%s\n", ser.BaseURL) fmt.Fprintf(w, "\tRoot:\t%s\n", ser.Root) + fmt.Fprintf(w, "\tSocket:\t%s\n", ser.Socket) fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address) fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert) fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey) diff --git a/cmd/config_init.go b/cmd/config_init.go index 62b727a5..48ec3873 100644 --- a/cmd/config_init.go +++ b/cmd/config_init.go @@ -43,6 +43,7 @@ override the options.`, ser := &settings.Server{ Address: mustGetString(flags, "address"), + Socket: mustGetString(flags, "socket"), Root: mustGetString(flags, "root"), BaseURL: mustGetString(flags, "baseurl"), TLSKey: mustGetString(flags, "key"), diff --git a/cmd/config_set.go b/cmd/config_set.go index f725fd45..5b417140 100644 --- a/cmd/config_set.go +++ b/cmd/config_set.go @@ -34,6 +34,8 @@ you want to change. Other options will remain unchanged.`, ser.BaseURL = mustGetString(flags, flag.Name) case "root": ser.Root = mustGetString(flags, flag.Name) + case "socket": + ser.Socket = mustGetString(flags, flag.Name) case "cert": ser.TLSCert = mustGetString(flags, flag.Name) case "key": diff --git a/cmd/root.go b/cmd/root.go index 016e8128..e1937870 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,13 +2,16 @@ package cmd import ( "crypto/tls" + "errors" "io/ioutil" "log" "net" "net/http" "os" + "os/signal" "path/filepath" "strings" + "syscall" "github.com/filebrowser/filebrowser/v2/auth" fbhttp "github.com/filebrowser/filebrowser/v2/http" @@ -50,6 +53,7 @@ func addServerFlags(flags *pflag.FlagSet) { flags.StringP("cert", "t", "", "tls certificate") flags.StringP("key", "k", "", "tls key") flags.StringP("root", "r", ".", "root to prepend to relative paths") + flags.String("socket", "", "socket to listen to (cannot be used with address, port, cert nor key flags)") flags.StringP("baseurl", "b", "", "base url") } @@ -109,7 +113,10 @@ user created with the credentials from options "username" and "password".`, var listener net.Listener - if server.TLSKey != "" && server.TLSCert != "" { + if server.Socket != "" { + listener, err = net.Listen("unix", server.Socket) + checkErr(err) + } else if server.TLSKey != "" && server.TLSCert != "" { cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) checkErr(err) listener, err = tls.Listen("tcp", adr, &tls.Config{Certificates: []tls.Certificate{cer}}) @@ -119,9 +126,15 @@ user created with the credentials from options "username" and "password".`, checkErr(err) } + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, os.Interrupt, syscall.SIGTERM) + go cleanupHandler(listener, sigc) + handler, err := fbhttp.NewHandler(d.store, server) checkErr(err) + defer listener.Close() + log.Println("Listening on", listener.Addr().String()) if err := http.Serve(listener, handler); err != nil { log.Fatal(err) @@ -129,6 +142,13 @@ user created with the credentials from options "username" and "password".`, }, pythonConfig{allowNoDB: true}), } +func cleanupHandler(listener net.Listener, c chan os.Signal) { + sig := <-c + log.Printf("Caught signal %s: shutting down.", sig) + listener.Close() + os.Exit(0) +} + func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server { server, err := st.Settings.GetServer() checkErr(err) @@ -141,24 +161,45 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server { server.BaseURL = val } - if val, set := getParamB(flags, "address"); set { - server.Address = val - } - - if val, set := getParamB(flags, "port"); set { - server.Port = val - } - if val, set := getParamB(flags, "log"); set { server.Log = val } + isSocketSet := false + isAddrSet := false + + if val, set := getParamB(flags, "address"); set { + server.Address = val + isAddrSet = isAddrSet || set + } + + if val, set := getParamB(flags, "port"); set { + server.Port = val + isAddrSet = isAddrSet || set + } + if val, set := getParamB(flags, "key"); set { server.TLSKey = val + isAddrSet = isAddrSet || set } if val, set := getParamB(flags, "cert"); set { server.TLSCert = val + isAddrSet = isAddrSet || set + } + + if val, set := getParamB(flags, "socket"); set { + server.Socket = val + isSocketSet = isSocketSet || set + } + + if isAddrSet && isSocketSet { + checkErr(errors.New("--socket flag cannot be used with --adress, --port, --key nor --cert")) + } + + // Do not use saved Socket if address was manually set. + if isAddrSet && server.Socket != "" { + server.Socket = "" } return server diff --git a/settings/settings.go b/settings/settings.go index c94c2452..104d9f30 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -32,6 +32,7 @@ func (s *Settings) GetRules() []rules.Rule { type Server struct { Root string `json:"root"` BaseURL string `json:"baseURL"` + Socket string `json:"socket"` TLSKey string `json:"tlsKey"` TLSCert string `json:"tlsCert"` Port string `json:"port"`