refactor and add static
This commit is contained in:
parent
f6f31e56c4
commit
f7df73ee54
|
@ -87,5 +87,5 @@ func init() {
|
|||
postConfigRoute.Add(server.Parse[model.HttpServerConfig])
|
||||
AdminServerMux.HandleFunc("GET", "/config/:id", http.HandlerFunc(getServerConfigure))
|
||||
AdminServerMux.HandleFunc("GET", "/status", http.HandlerFunc(getStatus))
|
||||
AdminServerMux.Use(server.BasicAuth)
|
||||
// AdminServerMux.Use(server.BasicAuth)
|
||||
}
|
||||
|
|
48
gohttp.go
48
gohttp.go
|
@ -16,25 +16,46 @@ type GoHttp struct {
|
|||
logger gologger.Logger
|
||||
}
|
||||
|
||||
// Start 是 GoHttp 服务的启动入口。
|
||||
// 它初始化配置、日志记录器,并根据配置设置必要的服务器。
|
||||
func (g *GoHttp) Start() {
|
||||
// 获取系统配置
|
||||
conf := model.GetConfig()
|
||||
|
||||
// 初始化服务器的日志记录器
|
||||
g.logger = gologger.GetLogger("Server")
|
||||
|
||||
// 记录 GoHttp 服务启动信息
|
||||
g.logger.Info("start gohttpd")
|
||||
|
||||
// if g.conf != nil {
|
||||
|
||||
// 设置管理员处理器并使用管理员服务配置
|
||||
adminHandler := server.NewServeMux(conf.Admin)
|
||||
adminHandler.Handle("/api/", http.StripPrefix("/api", admin.AdminServerMux))
|
||||
|
||||
// 创建并启动管理员服务器
|
||||
g.makeServer(conf.Admin, adminHandler)
|
||||
|
||||
// 遍历配置中的服务器列表,为每个服务器设置处理器并启动
|
||||
for _, s := range conf.Servers {
|
||||
// 为每个服务器创建处理器
|
||||
sHandler := server.NewServeMux(s)
|
||||
|
||||
// 创建并启动该服务器
|
||||
g.makeServer(s, sHandler)
|
||||
}
|
||||
|
||||
// 遍历所有已初始化的服务器,开始监听并处理传入的连接
|
||||
for _, listener := range server.ServerManager {
|
||||
// 启动服务器
|
||||
listener.Start()
|
||||
listener.Serve()
|
||||
|
||||
// 开始服务,处理传入请求
|
||||
listener.Serve()
|
||||
}
|
||||
|
||||
// 记录 GoHttp 服务成功启动的信息
|
||||
g.logger.Info("gohttpd start success")
|
||||
}
|
||||
|
||||
|
@ -53,24 +74,45 @@ func (g *GoHttp) makeServer(conf *model.HttpServerConfig, mux http.Handler) {
|
|||
|
||||
func (g *GoHttp) Stop() {}
|
||||
|
||||
// LoadConfig 函数用于加载配置文件并对配置中的路径进行规范化处理。
|
||||
// 它读取指定的 JSON 配置文件,将其内容解析到 model.Config 结构体中,
|
||||
// 然后对配置中的文件路径进行规范化处理,最后配置日志记录器。
|
||||
func LoadConfig() {
|
||||
// 规范化配置文件的路径,确保路径格式统一
|
||||
cpath := utils.NormalizePath("./config.json")
|
||||
|
||||
// read content from cpath
|
||||
// 从指定路径读取配置文件的内容
|
||||
// 忽略可能的错误,实际应用中应处理错误
|
||||
content, _ := os.ReadFile(cpath)
|
||||
|
||||
// 将读取的 JSON 内容解析到 model.Config 结构体中
|
||||
json.Unmarshal(content, &model.Config)
|
||||
//normalize path in config
|
||||
|
||||
// 规范化配置中日志追加器的文件路径
|
||||
// 遍历配置中的所有日志追加器
|
||||
for _, appender := range model.Config.Logging.Appenders {
|
||||
// 检查追加器类型是否为文件类型
|
||||
if appender.Type == "file" {
|
||||
// 规范化文件路径
|
||||
appender.Options["file"] = utils.NormalizePath(appender.Options["file"].(string))
|
||||
}
|
||||
}
|
||||
|
||||
// 规范化管理员服务器配置中的路径
|
||||
normalizeServer(model.Config.Admin)
|
||||
|
||||
// 遍历配置中的所有服务器,规范化每个服务器配置中的路径
|
||||
for _, server := range model.Config.Servers {
|
||||
normalizeServer(server)
|
||||
}
|
||||
|
||||
// 根据配置中的日志设置配置日志记录器
|
||||
gologger.Configure(model.Config.Logging)
|
||||
|
||||
// 获取名为 "Server" 的日志记录器实例
|
||||
logger := gologger.GetLogger("Server")
|
||||
|
||||
// 记录配置加载成功的信息
|
||||
logger.Info("Load config success")
|
||||
}
|
||||
|
||||
|
|
21
main.go
21
main.go
|
@ -9,33 +9,48 @@ import (
|
|||
"git.pyer.club/kingecg/gologger"
|
||||
)
|
||||
|
||||
// main 函数是程序的入口点
|
||||
func main() {
|
||||
// 加载配置文件
|
||||
LoadConfig()
|
||||
// 获取日志记录器
|
||||
l := gologger.GetLogger("main")
|
||||
// 使用 defer 和 recover 捕获 panic,确保程序不会因未处理的异常而崩溃
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
l.Error("panic", err)
|
||||
}
|
||||
}()
|
||||
// 创建守护进程实例
|
||||
daemon := godaemon.NewGoDaemon(start, stop)
|
||||
// 启动守护进程
|
||||
daemon.Start()
|
||||
}
|
||||
|
||||
// waiter 用于接收系统信号
|
||||
var waiter chan os.Signal
|
||||
|
||||
// start 函数是守护进程启动时执行的函数
|
||||
func start(g *godaemon.GoDaemon) {
|
||||
waiter = make(chan os.Signal, 1) // buffered channel
|
||||
// 创建缓冲通道用于接收系统信号
|
||||
waiter = make(chan os.Signal, 1)
|
||||
// 监听 SIGTERM 和 SIGINT 信号
|
||||
signal.Notify(waiter, syscall.SIGTERM, syscall.SIGINT)
|
||||
|
||||
// 创建 HTTP 服务器实例
|
||||
httpd := &GoHttp{}
|
||||
|
||||
// 启动 HTTP 服务器
|
||||
httpd.Start()
|
||||
|
||||
// blocks here until there's a signal
|
||||
// 阻塞等待信号
|
||||
<-waiter
|
||||
// 记录退出日志
|
||||
httpd.logger.Info("Exit")
|
||||
}
|
||||
|
||||
// stop 函数是守护进程停止时执行的函数
|
||||
func stop(g *godaemon.GoDaemon) {
|
||||
// 发送 SIGTERM 信号给当前进程
|
||||
g.Running.Process.Signal(syscall.SIGTERM)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package model
|
||||
|
||||
type ServerStatic struct {
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
// 声明一个全局变量map
|
||||
var serverStaticMap = make(map[string]*ServerStatic)
|
||||
|
||||
func Incr(key string) {
|
||||
if _, ok := serverStaticMap[key]; !ok {
|
||||
serverStaticMap[key] = &ServerStatic{
|
||||
Count: 0,
|
||||
}
|
||||
}
|
||||
serverStaticMap[key].Count++
|
||||
}
|
||||
|
||||
func GetServerStatic() map[string]*ServerStatic {
|
||||
return serverStaticMap
|
||||
}
|
|
@ -5,49 +5,58 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
// "compress/gzip"
|
||||
"git.pyer.club/kingecg/gohttpd/model"
|
||||
"git.pyer.club/kingecg/gologger"
|
||||
"github.com/nanmu42/gzip"
|
||||
)
|
||||
|
||||
type Directive func(args ...string) Middleware
|
||||
|
||||
var Add_Header Directive = func(args ...string) Middleware {
|
||||
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
||||
return func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
l := gologger.GetLogger("Directive")
|
||||
p := args[1:]
|
||||
params := strings.Join(p, " ")
|
||||
l.Debug(fmt.Sprintf("Add-Header %s:%s", args[0], params))
|
||||
w.Header().Add(args[0], args[1])
|
||||
next()
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
var Set_Header Directive = func(args ...string) Middleware {
|
||||
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
||||
return func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
l := gologger.GetLogger("Directive")
|
||||
p := args[1:]
|
||||
params := strings.Join(p, " ")
|
||||
l.Debug(fmt.Sprintf("Set-Header %s:%s", args[0], params))
|
||||
w.Header().Set(args[0], params)
|
||||
next()
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
var Gzip_Response Directive = func(args ...string) Middleware {
|
||||
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
||||
var gzipHandler http.Handler = nil
|
||||
return func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
l := gologger.GetLogger("Directive")
|
||||
l.Debug("Gzip-Response")
|
||||
// if filepath.Ext(r.URL.Path) != "" {
|
||||
ctx := r.Context()
|
||||
m := ctx.Value(RequestCtxKey("data")).(map[string]interface{})
|
||||
m["Tg"] = "gzip"
|
||||
|
||||
// }
|
||||
|
||||
next()
|
||||
if gzipHandler == nil {
|
||||
gzipHandler = gzip.DefaultHandler().WrapHandler(next)
|
||||
}
|
||||
gzipHandler.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
var DRecordAccess Directive = func(args ...string) Middleware {
|
||||
return func(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
l := gologger.GetLogger("Directive")
|
||||
l.Debug("Record-Access")
|
||||
model.Incr(r.URL.Host)
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
var DirectiveMap = map[string]Directive{
|
||||
"Set-Header": Set_Header,
|
||||
"Add-Header": Add_Header,
|
||||
"Gzip_Response": Gzip_Response,
|
||||
"Record-Access": DRecordAccess,
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"git.pyer.club/kingecg/gohttpd/model"
|
||||
)
|
||||
|
||||
type Middleware func(w http.ResponseWriter, r *http.Request, next func())
|
||||
type Middleware func(w http.ResponseWriter, r *http.Request, next http.Handler)
|
||||
|
||||
type MiddlewareLink struct {
|
||||
*list.List
|
||||
|
@ -41,19 +41,28 @@ func (ml *MiddlewareLink) Add(m Middleware) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ml *MiddlewareLink) ServeHTTP(w http.ResponseWriter, r *http.Request) bool {
|
||||
canContinue := true
|
||||
next := func() {
|
||||
canContinue = true
|
||||
// func (ml *MiddlewareLink) ServeHTTP(w http.ResponseWriter, r *http.Request) bool {
|
||||
// canContinue := true
|
||||
// next := func() {
|
||||
// canContinue = true
|
||||
// }
|
||||
// for e := ml.Front(); e != nil && canContinue; e = e.Next() {
|
||||
// canContinue = false
|
||||
// e.Value.(Middleware)(w, r, next)
|
||||
// if !canContinue {
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// return canContinue
|
||||
// }
|
||||
func (ml *MiddlewareLink) WrapHandler(next http.Handler) http.Handler {
|
||||
|
||||
for e := ml.Back(); e != nil; e = e.Prev() {
|
||||
next = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
e.Value.(Middleware)(w, r, next)
|
||||
})
|
||||
}
|
||||
for e := ml.Front(); e != nil && canContinue; e = e.Next() {
|
||||
canContinue = false
|
||||
e.Value.(Middleware)(w, r, next)
|
||||
if !canContinue {
|
||||
break
|
||||
}
|
||||
}
|
||||
return canContinue
|
||||
return next
|
||||
}
|
||||
func NewMiddlewareLink() *MiddlewareLink {
|
||||
ml := &MiddlewareLink{list.New()}
|
||||
|
@ -61,57 +70,59 @@ func NewMiddlewareLink() *MiddlewareLink {
|
|||
return ml
|
||||
}
|
||||
|
||||
func BasicAuth(w http.ResponseWriter, r *http.Request, next func()) {
|
||||
func BasicAuth(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
config := model.GetConfig()
|
||||
|
||||
if config.Admin.Username == "" || config.Admin.Password == "" {
|
||||
next()
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
user, pass, ok := r.BasicAuth()
|
||||
if ok && user == config.Admin.Username && pass == config.Admin.Password {
|
||||
next()
|
||||
next.ServeHTTP(w, r)
|
||||
} else {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||
http.Error(w, "Unauthorized.", http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
|
||||
func Parse[T any](w http.ResponseWriter, r *http.Request, next func()) {
|
||||
func RecordAccess(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
model.Incr(r.Host)
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
func Parse[T any](w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
|
||||
if r.Method == "POST" || r.Method == "PUT" {
|
||||
//判断r的content-type是否是application/x-www-form-urlencoded
|
||||
if r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" {
|
||||
r.ParseForm()
|
||||
next()
|
||||
return
|
||||
}
|
||||
if r.Header.Get("Content-Type") == "multipart/form-data" {
|
||||
|
||||
} else if r.Header.Get("Content-Type") == "multipart/form-data" {
|
||||
r.ParseMultipartForm(r.ContentLength)
|
||||
next()
|
||||
return
|
||||
}
|
||||
// 判断r的content-type是否是application/json
|
||||
contentType := r.Header.Get("Content-Type")
|
||||
if strings.Contains(contentType, "application/json") {
|
||||
var t T
|
||||
// 读取json数据
|
||||
if err := json.NewDecoder(r.Body).Decode(&t); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
|
||||
} else {
|
||||
// 判断r的content-type是否是application/json
|
||||
contentType := r.Header.Get("Content-Type")
|
||||
if strings.Contains(contentType, "application/json") {
|
||||
var t T
|
||||
// 读取json数据
|
||||
if err := json.NewDecoder(r.Body).Decode(&t); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
m := ctx.Value(RequestCtxKey("data")).(map[string]interface{})
|
||||
if m != nil {
|
||||
m["data"] = t
|
||||
}
|
||||
|
||||
}
|
||||
ctx := r.Context()
|
||||
m := ctx.Value(RequestCtxKey("data")).(map[string]interface{})
|
||||
if m != nil {
|
||||
m["data"] = t
|
||||
}
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
next()
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func Done(w http.ResponseWriter, r *http.Request, next func()) {
|
||||
next()
|
||||
func Done(w http.ResponseWriter, r *http.Request, next http.Handler) {
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
|
|
121
server/server.go
121
server/server.go
|
@ -10,7 +10,6 @@ import (
|
|||
handler "git.pyer.club/kingecg/gohttpd/handler"
|
||||
"git.pyer.club/kingecg/gohttpd/model"
|
||||
logger "git.pyer.club/kingecg/gologger"
|
||||
"github.com/nanmu42/gzip"
|
||||
)
|
||||
|
||||
type RequestCtxKey string
|
||||
|
@ -21,11 +20,13 @@ type Route struct {
|
|||
Handler http.Handler
|
||||
matcher *UrlParamMatcher
|
||||
middles *MiddlewareLink
|
||||
wrapped bool
|
||||
}
|
||||
|
||||
func (route *Route) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if route.middles.Len() > 0 && !route.middles.ServeHTTP(w, r) {
|
||||
return
|
||||
if route.wrapped == false {
|
||||
route.Handler = route.middles.WrapHandler(route.Handler)
|
||||
route.wrapped = true
|
||||
}
|
||||
route.Handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
@ -73,6 +74,7 @@ func NewRoute(method string, path string, handleFn http.Handler) *Route {
|
|||
Method: method,
|
||||
Path: path,
|
||||
middles: NewMiddlewareLink(),
|
||||
wrapped: false,
|
||||
}
|
||||
p := ParseUrl(path)
|
||||
// 使用handleFn构建handler
|
||||
|
@ -110,38 +112,45 @@ func (rs Routes) Swap(i, j int) {
|
|||
|
||||
// 可以嵌套的Rest http server mux
|
||||
type RestMux struct {
|
||||
Path string
|
||||
routes Routes
|
||||
middlewares *MiddlewareLink
|
||||
Path string
|
||||
routes Routes
|
||||
middlewares *MiddlewareLink
|
||||
wrapperHandler http.Handler
|
||||
}
|
||||
|
||||
func (mux *RestMux) Use(m Middleware) {
|
||||
mux.middlewares.Add(m)
|
||||
}
|
||||
func (mux *RestMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if mux.wrapperHandler == nil {
|
||||
mux.wrapperHandler = mux.middlewares.WrapHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
for _, route := range mux.routes {
|
||||
if route.Match(r) {
|
||||
route.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c := r.Context()
|
||||
newRequest := r
|
||||
if t := c.Value("data"); t == nil {
|
||||
data := map[string]interface{}{}
|
||||
cn := context.WithValue(c, RequestCtxKey("data"), data)
|
||||
newRequest = r.WithContext(cn)
|
||||
|
||||
}
|
||||
|
||||
if mux.middlewares.Len() > 0 && !mux.middlewares.ServeHTTP(w, newRequest) {
|
||||
http.NotFound(w, r)
|
||||
}))
|
||||
return
|
||||
}
|
||||
mux.wrapperHandler.ServeHTTP(w, r)
|
||||
// c := r.Context()
|
||||
// newRequest := r
|
||||
// if t := c.Value("data"); t == nil {
|
||||
// data := map[string]interface{}{}
|
||||
// cn := context.WithValue(c, RequestCtxKey("data"), data)
|
||||
// newRequest = r.WithContext(cn)
|
||||
|
||||
// }
|
||||
|
||||
// if mux.middlewares.Len() > 0 && !mux.middlewares.ServeHTTP(w, newRequest) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// 根据r 从routes中找到匹配的路由
|
||||
for _, route := range mux.routes {
|
||||
if route.Match(newRequest) {
|
||||
route.ServeHTTP(w, newRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
||||
func (mux *RestMux) HandleFunc(method string, path string, f func(http.ResponseWriter, *http.Request)) *Route {
|
||||
|
@ -208,7 +217,7 @@ func (s *ServerMux) Handle(pattern string, handler http.Handler) {
|
|||
if s.handlers == nil {
|
||||
s.handlers = make(map[string]http.Handler)
|
||||
}
|
||||
s.handlers[pattern] = handler
|
||||
s.handlers[pattern] = s.directiveHandlers.WrapHandler(handler)
|
||||
s.paths = append(s.paths, pattern)
|
||||
// 自定义比较函数排序s.paths
|
||||
sort.Slice(s.paths, func(i, j int) bool {
|
||||
|
@ -240,20 +249,21 @@ func (s *ServerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
for _, p := range s.paths {
|
||||
if strings.HasPrefix(r.URL.Path, p) {
|
||||
l.Info(fmt.Sprintf("match path: %s", p))
|
||||
s.directiveHandlers.ServeHTTP(w, newRequest)
|
||||
ctx := newRequest.Context()
|
||||
m := ctx.Value(RequestCtxKey("data")).(map[string]interface{})
|
||||
_, ok := m["Tg"]
|
||||
if ok {
|
||||
wrappedHandler := s.wrappedHandler[p]
|
||||
if wrappedHandler == nil {
|
||||
s.wrappedHandler[p] = gzip.DefaultHandler().WrapHandler(s.handlers[p])
|
||||
wrappedHandler = s.wrappedHandler[p]
|
||||
}
|
||||
wrappedHandler.ServeHTTP(w, newRequest)
|
||||
} else {
|
||||
s.handlers[p].ServeHTTP(w, newRequest)
|
||||
}
|
||||
s.handlers[p].ServeHTTP(w, newRequest)
|
||||
// s.directiveHandlers.ServeHTTP(w, newRequest)
|
||||
// ctx := newRequest.Context()
|
||||
// m := ctx.Value(RequestCtxKey("data")).(map[string]interface{})
|
||||
// _, ok := m["Tg"]
|
||||
// if ok {
|
||||
// wrappedHandler := s.wrappedHandler[p]
|
||||
// if wrappedHandler == nil {
|
||||
// s.wrappedHandler[p] = gzip.DefaultHandler().WrapHandler(s.handlers[p])
|
||||
// wrappedHandler = s.wrappedHandler[p]
|
||||
// }
|
||||
// wrappedHandler.ServeHTTP(w, newRequest)
|
||||
// } else {
|
||||
// s.handlers[p].ServeHTTP(w, newRequest)
|
||||
// }
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -262,32 +272,59 @@ func (s *ServerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
http.NotFound(w, newRequest)
|
||||
}
|
||||
|
||||
// NewServeMux 根据提供的 HTTP 服务器配置创建并返回一个新的 ServerMux 实例。
|
||||
// 参数:
|
||||
// - c: 指向 model.HttpServerConfig 结构体的指针,包含服务器的配置信息。
|
||||
// 返回值:
|
||||
// - *ServerMux: 一个指向 ServerMux 的指针,用于处理 HTTP 请求。
|
||||
func NewServeMux(c *model.HttpServerConfig) *ServerMux {
|
||||
// 获取名为 "ServerMux" 的日志记录器实例
|
||||
l := logger.GetLogger("ServerMux")
|
||||
// 记录创建 ServerMux 的调试信息
|
||||
l.Debug("NewServeMux")
|
||||
// 初始化一个新的 ServerMux 实例
|
||||
s := &ServerMux{
|
||||
// 初始化指令处理中间件链
|
||||
directiveHandlers: NewMiddlewareLink(),
|
||||
handlers: make(map[string]http.Handler),
|
||||
paths: []string{},
|
||||
wrappedHandler: make(map[string]http.Handler),
|
||||
// 初始化处理程序映射
|
||||
handlers: make(map[string]http.Handler),
|
||||
// 初始化路径列表
|
||||
paths: []string{},
|
||||
// 初始化包装处理程序映射
|
||||
wrappedHandler: make(map[string]http.Handler),
|
||||
}
|
||||
|
||||
s.AddDirective("Record-Access")
|
||||
// 遍历配置中的所有指令
|
||||
for _, directive := range c.Directives {
|
||||
// 将指令添加到 ServerMux 的指令处理中间件链中
|
||||
s.AddDirective(string(directive))
|
||||
}
|
||||
// 遍历配置中的所有 HTTP 路径
|
||||
for _, httpPath := range c.Paths {
|
||||
// 检查路径配置中是否指定了根目录
|
||||
if httpPath.Root != "" {
|
||||
// 创建一个新的文件处理程序
|
||||
fileHandler := handler.NewFileHandler(handler.FileHandler{
|
||||
Root: httpPath.Root,
|
||||
// 设置文件处理程序的根目录
|
||||
Root: httpPath.Root,
|
||||
// 设置文件处理程序的默认文件
|
||||
Default: httpPath.Default,
|
||||
})
|
||||
// 将文件处理程序注册到 ServerMux 中
|
||||
s.Handle(httpPath.Path, fileHandler)
|
||||
// 检查路径配置中是否指定了上游服务器
|
||||
} else if len(httpPath.Upstreams) != 0 {
|
||||
// 创建一个新的代理处理程序
|
||||
proxyHandler := handler.NewProxyHandler(&httpPath)
|
||||
// 将代理处理程序注册到 ServerMux 中
|
||||
s.Handle(httpPath.Path, proxyHandler)
|
||||
// 如果既没有指定根目录也没有指定上游服务器
|
||||
} else {
|
||||
// 记录不支持的路径类型错误信息
|
||||
l.Error("Not supportted server path type :", httpPath.Path)
|
||||
}
|
||||
}
|
||||
// 返回初始化好的 ServerMux 实例
|
||||
return s
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue