From 7d20a01dba5cf379b93bbc539d3de04545a739ec Mon Sep 17 00:00:00 2001 From: Andy Hsu Date: Tue, 4 Jul 2023 17:56:02 +0800 Subject: [PATCH] feat!: support listen to the unix (close #4671) Starting from this commit, the HTTP server related config all move to the scheme --- cmd/server.go | 46 ++++++++++++++++++++++++++++--------- internal/conf/config.go | 27 +++++++++++++--------- server/middlewares/https.go | 2 +- server/router.go | 2 +- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/cmd/server.go b/cmd/server.go index 4b1edd14e8b..0eea0899c26 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -3,6 +3,7 @@ package cmd import ( "context" "fmt" + "net" "net/http" "os" "os/signal" @@ -42,26 +43,40 @@ the address is defined in config file`, r := gin.New() r.Use(gin.LoggerWithWriter(log.StandardLogger().Out), gin.RecoveryWithWriter(log.StandardLogger().Out)) server.Init(r) - var httpSrv, httpsSrv *http.Server - if !conf.Conf.Scheme.DisableHttp { - httpBase := fmt.Sprintf("%s:%d", conf.Conf.Address, conf.Conf.Port) + var httpSrv, httpsSrv, unixSrv *http.Server + if conf.Conf.Scheme.HttpPort != -1 { + httpBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpPort) utils.Log.Infof("start HTTP server @ %s", httpBase) httpSrv = &http.Server{Addr: httpBase, Handler: r} go func() { err := httpSrv.ListenAndServe() if err != nil && err != http.ErrServerClosed { - utils.Log.Fatalf("failed to start: %s", err.Error()) + utils.Log.Fatalf("failed to start http: %s", err.Error()) } }() } - if conf.Conf.Scheme.Https { - httpsBase := fmt.Sprintf("%s:%d", conf.Conf.Address, conf.Conf.HttpsPort) + if conf.Conf.Scheme.HttpsPort != -1 { + httpsBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpPort) utils.Log.Infof("start HTTPS server @ %s", httpsBase) httpsSrv = &http.Server{Addr: httpsBase, Handler: r} go func() { err := httpsSrv.ListenAndServeTLS(conf.Conf.Scheme.CertFile, conf.Conf.Scheme.KeyFile) if err != nil && err != http.ErrServerClosed { - utils.Log.Fatalf("failed to start: %s", err.Error()) + utils.Log.Fatalf("failed to start https: %s", err.Error()) + } + }() + } + if conf.Conf.Scheme.UnixFile != "" { + utils.Log.Infof("start unix server @ %s", conf.Conf.Scheme.UnixFile) + unixSrv = &http.Server{Handler: r} + go func() { + listener, err := net.Listen("unix", conf.Conf.Scheme.UnixFile) + if err != nil { + utils.Log.Fatalf("failed to listen unix: %+v", err) + } + err = unixSrv.Serve(listener) + if err != nil && err != http.ErrServerClosed { + utils.Log.Fatalf("failed to start unix: %s", err.Error()) } }() } @@ -78,21 +93,30 @@ the address is defined in config file`, ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() var wg sync.WaitGroup - if !conf.Conf.Scheme.DisableHttp { + if conf.Conf.Scheme.HttpPort != -1 { wg.Add(1) go func() { defer wg.Done() if err := httpSrv.Shutdown(ctx); err != nil { - utils.Log.Fatal("HTTP server shutdown:", err) + utils.Log.Fatal("HTTP server shutdown err: ", err) } }() } - if conf.Conf.Scheme.Https { + if conf.Conf.Scheme.HttpsPort != -1 { wg.Add(1) go func() { defer wg.Done() if err := httpsSrv.Shutdown(ctx); err != nil { - utils.Log.Fatal("HTTPS server shutdown:", err) + utils.Log.Fatal("HTTPS server shutdown err: ", err) + } + }() + } + if conf.Conf.Scheme.UnixFile != "" { + wg.Add(1) + go func() { + defer wg.Done() + if err := unixSrv.Shutdown(ctx); err != nil { + utils.Log.Fatal("Unix server shutdown err: ", err) } }() } diff --git a/internal/conf/config.go b/internal/conf/config.go index d0c8709365d..39838754c77 100644 --- a/internal/conf/config.go +++ b/internal/conf/config.go @@ -20,11 +20,13 @@ type Database struct { } type Scheme struct { - DisableHttp bool `json:"disable_http" env:"DISABLE_HTTP"` - Https bool `json:"https" env:"HTTPS"` - ForceHttps bool `json:"force_https" env:"FORCE_HTTPS"` - CertFile string `json:"cert_file" env:"CERT_FILE"` - KeyFile string `json:"key_file" env:"KEY_FILE"` + Address string `json:"address" env:"ADDR"` + HttpPort int `json:"http_port" env:"HTTP_PORT"` + HttpsPort int `json:"https_port" env:"HTTPS_PORT"` + ForceHttps bool `json:"force_https" env:"FORCE_HTTPS"` + CertFile string `json:"cert_file" env:"CERT_FILE"` + KeyFile string `json:"key_file" env:"KEY_FILE"` + UnixFile string `json:"unix_file" env:"UNIX_FILE"` } type LogConfig struct { @@ -38,9 +40,6 @@ type LogConfig struct { type Config struct { Force bool `json:"force" env:"FORCE"` - Address string `json:"address" env:"ADDR"` - Port int `json:"port" env:"PORT"` - HttpsPort int `json:"https_port" env:"HTTPS_PORT"` SiteURL string `json:"site_url" env:"SITE_URL"` Cdn string `json:"cdn" env:"CDN"` JwtSecret string `json:"jwt_secret" env:"JWT_SECRET"` @@ -61,9 +60,15 @@ func DefaultConfig() *Config { logPath := filepath.Join(flags.DataDir, "log/log.log") dbPath := filepath.Join(flags.DataDir, "data.db") return &Config{ - Address: "0.0.0.0", - Port: 5244, - HttpsPort: 5245, + Scheme: Scheme{ + Address: "0.0.0.0", + UnixFile: "", + HttpPort: 5244, + HttpsPort: -1, + ForceHttps: false, + CertFile: "", + KeyFile: "", + }, JwtSecret: random.String(16), TokenExpiresIn: 48, TempDir: tempDir, diff --git a/server/middlewares/https.go b/server/middlewares/https.go index bb628be1e7d..8c71eb71ff1 100644 --- a/server/middlewares/https.go +++ b/server/middlewares/https.go @@ -12,7 +12,7 @@ func ForceHttps(c *gin.Context) { if c.Request.TLS == nil { host := c.Request.Host // change port to https port - host = strings.Replace(host, fmt.Sprintf(":%d", conf.Conf.Port), fmt.Sprintf(":%d", conf.Conf.HttpsPort), 1) + host = strings.Replace(host, fmt.Sprintf(":%d", conf.Conf.Scheme.HttpPort), fmt.Sprintf(":%d", conf.Conf.Scheme.HttpsPort), 1) c.Redirect(302, "https://"+host+c.Request.RequestURI) c.Abort() return diff --git a/server/router.go b/server/router.go index 6a483cfef31..c6de5611189 100644 --- a/server/router.go +++ b/server/router.go @@ -21,7 +21,7 @@ func Init(e *gin.Engine) { } Cors(e) g := e.Group(conf.URL.Path) - if conf.Conf.Scheme.Https && conf.Conf.Scheme.ForceHttps && !conf.Conf.Scheme.DisableHttp { + if conf.Conf.Scheme.HttpPort != -1 && conf.Conf.Scheme.HttpsPort != -1 && conf.Conf.Scheme.ForceHttps { g.Use(middlewares.ForceHttps) } g.Any("/ping", func(c *gin.Context) {