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