diff --git a/cfg/config.go b/cfg/config.go index 4d5da1f..2e1c748 100644 --- a/cfg/config.go +++ b/cfg/config.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "os" - "strconv" "github.com/go-ini/ini" ) @@ -24,7 +23,7 @@ var ( UserHypha string HeaderLinksHypha string - HTTPPort string + ListenAddr string URL string GeminiCertificatePath string @@ -62,8 +61,8 @@ type Hyphae struct { // Network is a section of Config that has fields related to network stuff: // HTTP and Gemini. type Network struct { - HTTPPort uint64 - URL string `comment:"Set your wiki's public URL here. It's used for OpenGraph generation and syndication feeds."` + ListenAddr string + URL string `comment:"Set your wiki's public URL here. It's used for OpenGraph generation and syndication feeds."` } // CustomScripts is a section with paths to JavaScript files that are loaded on @@ -97,8 +96,8 @@ func ReadConfigFile(path string) error { HeaderLinksHypha: "", }, Network: Network{ - HTTPPort: 1737, - URL: "", + ListenAddr: "127.0.0.1:1737", + URL: "", }, Authorization: Authorization{ UseAuth: false, @@ -138,12 +137,12 @@ func ReadConfigFile(path string) error { // doesn't exist or is empty. f.MapTo(cfg) - // Check for PORT env var and use it, if present + if os.Getenv("LISTEN_ADDR") != "" { + cfg.Network.ListenAddr = os.Getenv("LISTEN_ADDR") + } + if os.Getenv("PORT") != "" { - port, err := strconv.ParseUint(os.Getenv("PORT"), 10, 64) - if err == nil { - cfg.Network.HTTPPort = port - } + cfg.Network.ListenAddr = "127.0.0.1:" + os.Getenv("PORT") } // Map the struct to the global variables @@ -152,7 +151,7 @@ func ReadConfigFile(path string) error { HomeHypha = cfg.HomeHypha UserHypha = cfg.UserHypha HeaderLinksHypha = cfg.HeaderLinksHypha - HTTPPort = strconv.FormatUint(cfg.HTTPPort, 10) + ListenAddr = cfg.ListenAddr URL = cfg.URL UseAuth = cfg.UseAuth AllowRegistration = cfg.AllowRegistration @@ -163,7 +162,7 @@ func ReadConfigFile(path string) error { // This URL makes much more sense. if URL == "" { - URL = "http://0.0.0.0:" + HTTPPort + URL = "http://" + ListenAddr } return nil diff --git a/httpd.go b/httpd.go new file mode 100644 index 0000000..dcaab4d --- /dev/null +++ b/httpd.go @@ -0,0 +1,54 @@ +package main + +import ( + "log" + "net" + "net/http" + "os" + "strings" + "time" + + "github.com/bouncepaw/mycorrhiza/cfg" +) + +func serveHTTP() { + server := &http.Server{ + ReadTimeout: 300 * time.Second, + WriteTimeout: 300 * time.Second, + IdleTimeout: 300 * time.Second, + Handler: http.DefaultServeMux, + } + + if strings.HasPrefix(cfg.ListenAddr, "/") { + startUnixSocketServer(server, cfg.ListenAddr) + } else { + server.Addr = cfg.ListenAddr + startHTTPServer(server) + } +} + +func startUnixSocketServer(server *http.Server, socketFile string) { + os.Remove(socketFile) + + listener, err := net.Listen("unix", socketFile) + if err != nil { + log.Fatalf("Failed to start a server: %v", err) + } + defer listener.Close() + + if err := os.Chmod(socketFile, 0666); err != nil { + log.Fatalf("Failed to set socket permissions: %v", err) + } + + log.Printf("Listening on Unix socket %s", cfg.ListenAddr) + if err := server.Serve(listener); err != http.ErrServerClosed { + log.Fatalf("Failed to start a server: %v", err) + } +} + +func startHTTPServer(server *http.Server) { + log.Printf("Listening on %s", server.Addr) + if err := server.ListenAndServe(); err != http.ErrServerClosed { + log.Fatalf("Failed to start a server: %v", err) + } +} diff --git a/main.go b/main.go index bb8585f..46b3f8a 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ package main import ( "log" - "net/http" "os" "github.com/bouncepaw/mycorrhiza/cfg" @@ -48,5 +47,5 @@ func main() { // Network: web.Init() - log.Fatal(http.ListenAndServe("0.0.0.0:"+cfg.HTTPPort, nil)) + serveHTTP() }