diff --git a/go.mod b/go.mod index ecc1556..57454e3 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.1 github.com/nanmu42/gzip v1.2.0 github.com/samber/lo v1.39.0 + golang.org/x/crypto v0.39.0 ) @@ -29,11 +30,10 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/signalsciences/ac v1.2.0 // indirect github.com/ugorji/go/codec v1.2.6 // indirect - golang.org/x/crypto v0.38.0 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect golang.org/x/net v0.40.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.25.0 // indirect + golang.org/x/text v0.26.0 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 8e69a08..ba08eea 100644 --- a/go.sum +++ b/go.sum @@ -84,8 +84,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -110,8 +110,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= diff --git a/gohttp.go b/gohttp.go index 6c21346..75be866 100644 --- a/gohttp.go +++ b/gohttp.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" "os" + "path/filepath" "git.pyer.club/kingecg/gohttpd/admin" "git.pyer.club/kingecg/gohttpd/model" @@ -102,6 +103,26 @@ func LoadConfig() { // 规范化管理员服务器配置中的路径 normalizeServer(model.Config.Admin) + if model.Config.IncludDir != "" { + model.Config.IncludDir = utils.NormalizePath(model.Config.IncludDir) + configs, err := filepath.Glob(model.Config.IncludDir + "/*.json") + if err == nil { + for _, config := range configs { + server := model.HttpServerConfig{} + // read config content and unmarshal + content, err := os.ReadFile(config) + if err == nil { + err = json.Unmarshal(content, &server) + if err == nil { + server.ConfPath = config + normalizeServer(&server) + model.Config.Servers = append(model.Config.Servers, &server) + } + } + } + } + } + // 遍历配置中的所有服务器,规范化每个服务器配置中的路径 for _, server := range model.Config.Servers { normalizeServer(server) @@ -120,13 +141,28 @@ func LoadConfig() { func normalizeServer(server *model.HttpServerConfig) { for index, path := range server.Paths { if path.Root != "" { - server.Paths[index].Root = utils.NormalizePath(path.Root) + if server.ConfPath != "" { + server.Paths[index].Root = utils.NormalizePathWithR(server.ConfPath, path.Root) + } else { + server.Paths[index].Root = utils.NormalizePath(path.Root) + } + } } if server.CertFile != "" { - server.CertFile = utils.NormalizePath(server.CertFile) + if server.ConfPath != "" { + server.CertFile = utils.NormalizePathWithR(server.ConfPath, server.CertFile) + } else { + server.CertFile = utils.NormalizePath(server.CertFile) + } + // server.CertFile = utils.NormalizePath(server.CertFile) } if server.KeyFile != "" { - server.KeyFile = utils.NormalizePath(server.KeyFile) + if server.ConfPath != "" { + server.KeyFile = utils.NormalizePathWithR(server.ConfPath, server.KeyFile) + } else { + server.KeyFile = utils.NormalizePath(server.KeyFile) + } + // server.KeyFile = utils.NormalizePath(server.KeyFile) } } diff --git a/model/model.go b/model/model.go index c835365..bae7861 100644 --- a/model/model.go +++ b/model/model.go @@ -40,11 +40,13 @@ type HttpServerConfig struct { Paths []HttpPath `json:"paths"` Username string `json:"username"` Password string `json:"password"` + EnableSSL bool `json:"enable_ssl"` CertFile string `json:"certfile"` KeyFile string `json:"keyfile"` Directives []string `json:"directives"` AuthType string `json:"auth_type"` Jwt *JwtConfig `json:"jwt"` + ConfPath string // 配置文件路径,在加载配置时写入,如果没有就是主配置文件的路径 // 健康检查配置 // 访问控制配置 @@ -60,9 +62,10 @@ type JwtConfig struct { } type GoHttpdConfig struct { - Logging gologger.LoggersConfig `json:"logging"` - Admin *HttpServerConfig `json:"admin"` - Servers []*HttpServerConfig `json:"servers"` + Logging gologger.LoggersConfig `json:"logging"` + Admin *HttpServerConfig `json:"admin"` + IncludDir string `json:"includ_dir"` + Servers []*HttpServerConfig `json:"servers"` } var DefaultAdminConfig HttpServerConfig = HttpServerConfig{ diff --git a/server/autossl.go b/server/autossl.go new file mode 100644 index 0000000..9de31b3 --- /dev/null +++ b/server/autossl.go @@ -0,0 +1,29 @@ +package server + +import ( + "context" + "crypto/tls" + + "git.pyer.club/kingecg/gohttpd/utils" + "golang.org/x/crypto/acme/autocert" +) + +var CertManager *autocert.Manager + +func InitCertManager(certDir string) { + CertManager = &autocert.Manager{ + Prompt: autocert.AcceptTOS, + HostPolicy: hostPolicy, + Cache: autocert.DirCache(utils.NormalizePath(certDir)), + } +} + +func GetTlsConfig() *tls.Config { + if CertManager == nil { + InitCertManager(utils.NormalizePath("./certs")) + } + return CertManager.TLSConfig() +} +func hostPolicy(ctx context.Context, host string) error { + return nil +} diff --git a/server/manager.go b/server/manager.go index 87c5d35..4da617c 100644 --- a/server/manager.go +++ b/server/manager.go @@ -112,8 +112,13 @@ func (s *ServerListener) StartServer(name string) { server.l.Listener = s.listener.Match(makeMatcher(serverName, s)) } - if server.Conf.CertFile != "" && server.Conf.KeyFile != "" { - err = server.ServeTLS(server.l, server.Conf.CertFile, server.Conf.KeyFile) + if server.Conf.EnableSSL { + if server.Conf.CertFile != "" && server.Conf.KeyFile != "" { + err = server.ServeTLS(server.l, server.Conf.CertFile, server.Conf.KeyFile) + } else { + server.Server.TLSConfig = GetTlsConfig() + err = server.ServeTLS(server.l, "", "") + } } else { err = server.Serve(server.l) } diff --git a/utils/util.go b/utils/util.go index 3d65531..3b55810 100644 --- a/utils/util.go +++ b/utils/util.go @@ -24,11 +24,15 @@ func GetExecDir() string { func NormalizePath(path string) string { // return filepath.ToSlash(filepath.Clean(path)) + return NormalizePathWithR(GetExecDir(), path) + +} + +func NormalizePathWithR(rootDir, path string) string { p := filepath.ToSlash(path) if filepath.IsAbs(p) { return p } else { - return filepath.Join(GetExecDir(), p) + return filepath.Join(rootDir, p) } - }