diff --git a/server/README.md b/server/README.md index 3e4f316..f6524ec 100644 --- a/server/README.md +++ b/server/README.md @@ -28,6 +28,7 @@ The configuration file path is `/etc/kvm/server.yaml`. ```yaml # Network Settings proto: http # Access protocol. Can be changed to `https` only when certificates are configured. Default is `http` +host: 0.0.0.0 # The listening address for the HTTP/HTTPS service. port: http: 80 # The listening port for the HTTP service. Default is `80` https: 443 # The listening port for the HTTPS service (effective when HTTPS is enabled). Default is `443` diff --git a/server/README_JA.md b/server/README_JA.md index 55a6f40..aa9d194 100644 --- a/server/README_JA.md +++ b/server/README_JA.md @@ -27,6 +27,7 @@ server ```yaml proto: http +host: 0.0.0.0 port: http: 80 https: 443 diff --git a/server/README_ZH.md b/server/README_ZH.md index ed26a0a..893474b 100644 --- a/server/README_ZH.md +++ b/server/README_ZH.md @@ -26,6 +26,7 @@ server ```yaml # 网络设置 proto: http # 访问协议,默认为 `http`,仅当配置了证书时支持改为 `https` +host: 0.0.0.0 port: http: 80 # HTTP 服务的监听端口,默认为 `80` https: 443 # HTTPS 服务的监听端口(启用 https 协议时生效),默认为 `443` diff --git a/server/config/default.go b/server/config/default.go index 987c317..7d74eeb 100644 --- a/server/config/default.go +++ b/server/config/default.go @@ -2,6 +2,7 @@ package config var defaultConfig = &Config{ Proto: "http", + Host: "0.0.0.0", Port: Port{ Http: 80, Https: 443, diff --git a/server/config/types.go b/server/config/types.go index 40df073..902ffa5 100644 --- a/server/config/types.go +++ b/server/config/types.go @@ -2,6 +2,7 @@ package config type Config struct { Proto string `yaml:"proto"` + Host string `yaml:"host"` Port Port `yaml:"port"` Cert Cert `yaml:"cert"` Logger Logger `yaml:"logger"` diff --git a/server/main.go b/server/main.go index baefcfb..e2beb69 100644 --- a/server/main.go +++ b/server/main.go @@ -5,6 +5,7 @@ import ( "log" "os" "os/signal" + "strconv" "syscall" "time" @@ -67,10 +68,11 @@ func run() { router.Init(r) - httpAddr := fmt.Sprintf(":%d", conf.Port.Http) - httpsAddr := fmt.Sprintf(":%d", conf.Port.Https) + httpAddr := fmt.Sprintf("%s:%d", conf.Host, conf.Port.Http) if conf.Proto == "https" { + httpsAddr := fmt.Sprintf("%s:%d", conf.Host, conf.Port.Https) + go func() { err := r.RunTLS(httpsAddr, conf.Cert.Crt, conf.Cert.Key) if err != nil { @@ -80,7 +82,7 @@ func run() { if err := middleware.ListenAndServeLoopbackHTTPRedirect( httpAddr, - httpsAddr, + strconv.Itoa(conf.Port.Https), r, router.PicoclawLoopbackHTTPAllowedPaths()..., ); err != nil { diff --git a/server/middleware/loopback_http.go b/server/middleware/loopback_http.go index 2ffe0ba..fd47688 100644 --- a/server/middleware/loopback_http.go +++ b/server/middleware/loopback_http.go @@ -10,7 +10,7 @@ import ( ) func ListenAndServeLoopbackHTTPRedirect( - httpPort string, + httpAddr string, httpsPort string, handler http.Handler, allowedPaths ...string, @@ -23,7 +23,7 @@ func ListenAndServeLoopbackHTTPRedirect( allowlist[path] = struct{}{} } - return http.ListenAndServe(httpPort, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + return http.ListenAndServe(httpAddr, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { if isLoopbackAllowedPath(req, allowlist) { if hasValidLoopbackHTTPToken(req) { handler.ServeHTTP(w, req) @@ -35,16 +35,14 @@ func ListenAndServeLoopbackHTTPRedirect( } host := req.Host - if strings.Contains(host, httpPort) { - host = strings.Split(host, httpPort)[0] + if h, _, err := net.SplitHostPort(host); err == nil { + host = h + } + if httpsPort != "443" { + host = net.JoinHostPort(host, httpsPort) } - targetURL := "https://" + host + req.URL.String() - if httpsPort != ":443" { - targetURL = "https://" + host + httpsPort + req.URL.String() - } - - http.Redirect(w, req, targetURL, http.StatusTemporaryRedirect) + http.Redirect(w, req, "https://"+host+req.URL.RequestURI(), http.StatusTemporaryRedirect) })) }