add servermux impl and directive support
This commit is contained in:
parent
33c988a952
commit
fab22c1c2d
|
@ -0,0 +1,22 @@
|
|||
package server
|
||||
|
||||
import "net/http"
|
||||
|
||||
type Directive func(args ...string) Middleware
|
||||
|
||||
var Add_Header Directive = func(args ...string) Middleware {
|
||||
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
||||
w.Header().Add(args[0], args[1])
|
||||
}
|
||||
}
|
||||
|
||||
var Set_Header Directive = func(args ...string) Middleware {
|
||||
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
||||
w.Header().Set(args[0], args[1])
|
||||
}
|
||||
}
|
||||
|
||||
var DirectiveMap = map[string]Directive{
|
||||
"Set-Header": Set_Header,
|
||||
"Add-Header": Add_Header,
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type ProxyRequestUpdater func(arg ...string) func(r *http.Request)
|
||||
|
||||
var ProxyRequestUpdateMap = map[string]ProxyRequestUpdater{
|
||||
"Host": func(arg ...string) func(r *http.Request) {
|
||||
return func(r *http.Request) {
|
||||
r.Host = arg[0]
|
||||
}
|
||||
},
|
||||
"Path": func(arg ...string) func(r *http.Request) {
|
||||
replace := arg[0]
|
||||
with := arg[1]
|
||||
return func(r *http.Request) {
|
||||
r.URL.Path = r.URL.Path[len(replace):]
|
||||
r.URL.Path = with + r.URL.Path
|
||||
}
|
||||
},
|
||||
"RemoveCookie": func(arg ...string) func(r *http.Request) {
|
||||
cookie := arg[0]
|
||||
return func(r *http.Request) {
|
||||
cookies := r.Cookies()
|
||||
_, index, ok := lo.FindIndexOf(cookies, func(v *http.Cookie) bool {
|
||||
return v.Name == cookie
|
||||
})
|
||||
if ok {
|
||||
r.Header.Del("Cookie")
|
||||
if len(cookies) == 1 {
|
||||
return
|
||||
}
|
||||
cookies = append(cookies[:index], cookies[index+1:]...)
|
||||
for _, cookie := range cookies {
|
||||
r.AddCookie(cookie)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func GetUpdaterFn(directive string) func(r *http.Request) {
|
||||
strs := strings.Split(directive, " ")
|
||||
if len(strs) > 1 {
|
||||
updater, ok := ProxyRequestUpdateMap[strs[0]]
|
||||
if ok {
|
||||
return updater(strs[1:]...)
|
||||
}
|
||||
} else {
|
||||
updater, ok := ProxyRequestUpdateMap[directive]
|
||||
if ok {
|
||||
return updater()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -187,3 +187,44 @@ func NewRestMux(path string) *RestMux {
|
|||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type ServerMux struct {
|
||||
http.Handler
|
||||
directiveHandlers *MiddlewareLink
|
||||
handlers map[string]http.Handler
|
||||
paths []string
|
||||
}
|
||||
|
||||
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.paths = append(s.paths, pattern)
|
||||
// 自定义比较函数排序s.paths
|
||||
sort.Slice(s.paths, func(i, j int) bool {
|
||||
return len(s.paths[i]) > len(s.paths[j]) || s.paths[i] > s.paths[j]
|
||||
})
|
||||
}
|
||||
|
||||
func (s *ServerMux) AddDirective(directiveStr string) {
|
||||
//TODO: 根据字符串内容生成一个中间件链,等directive实现再来补充逻辑
|
||||
strs := strings.Split(directiveStr, " ")
|
||||
directiveName := strs[0]
|
||||
params := strs[1:]
|
||||
directive, ok := DirectiveMap[directiveName]
|
||||
if ok {
|
||||
s.directiveHandlers.Add(directive(params...))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ServerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
for _, p := range s.paths {
|
||||
if strings.HasPrefix(r.URL.Path, p) {
|
||||
s.directiveHandlers.ServeHTTP(w, r)
|
||||
s.handlers[p].ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue