refactor route
This commit is contained in:
parent
d6752cd324
commit
18e319b407
|
@ -6,12 +6,6 @@ import (
|
|||
"git.pyer.club/kingecg/gohttpd/server"
|
||||
)
|
||||
|
||||
type Route struct {
|
||||
Method string
|
||||
Path string
|
||||
Handle http.HandlerFunc
|
||||
}
|
||||
|
||||
func about(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("About Page"))
|
||||
|
@ -22,10 +16,10 @@ func setConfig(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
}
|
||||
|
||||
var AdminRoutes = []Route{
|
||||
var AdminRoutes = []server.Route{
|
||||
// Admin Routes
|
||||
{"GET", "/about", about},
|
||||
{"Post", "/config", setConfig},
|
||||
{Method: "GET", Path: "/about", Handle: about},
|
||||
{Method: "Post", Path: "/config", Handle: setConfig},
|
||||
}
|
||||
|
||||
var AdminServerMux *server.RestMux
|
||||
|
|
138
server/server.go
138
server/server.go
|
@ -3,18 +3,82 @@ package server
|
|||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type RequestCtxKey string
|
||||
|
||||
type Route struct {
|
||||
Method string
|
||||
Path string
|
||||
Handle http.HandlerFunc
|
||||
Handler http.Handler
|
||||
matcher *UrlParamMatcher
|
||||
}
|
||||
|
||||
func (route *Route) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if route.Handler != nil {
|
||||
route.Handler.ServeHTTP(w, r)
|
||||
} else {
|
||||
route.Handle(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (route *Route) Match(r *http.Request) bool {
|
||||
if route.Method != "" && route.Method != r.Method {
|
||||
return false
|
||||
}
|
||||
|
||||
if route.matcher != nil {
|
||||
params, matched := MatchUrlParam(r.URL.Path, route.matcher)
|
||||
if matched {
|
||||
ctx := r.Context()
|
||||
data := ctx.Value(RequestCtxKey("data")).(map[string]interface{})
|
||||
for _, p := range route.matcher.Params {
|
||||
data[p] = params[p]
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
if route.Path == "" {
|
||||
return true
|
||||
}
|
||||
return strings.HasPrefix(r.URL.Path, route.Path)
|
||||
}
|
||||
|
||||
type Routes []*Route
|
||||
|
||||
func (rs Routes) Less(i, j int) bool {
|
||||
iPaths := strings.Split(rs[i].Path, "/")
|
||||
jPaths := strings.Split(rs[j].Path, "/")
|
||||
if len(iPaths) > len(jPaths) {
|
||||
return true
|
||||
}
|
||||
if len(iPaths) < len(jPaths) {
|
||||
return false
|
||||
}
|
||||
for k := 0; k < len(iPaths); k++ {
|
||||
if iPaths[k] != jPaths[k] {
|
||||
return iPaths[k] < jPaths[k]
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rs Routes) Len() int {
|
||||
return len(rs)
|
||||
}
|
||||
|
||||
func (rs Routes) Swap(i, j int) {
|
||||
rs[i], rs[j] = rs[j], rs[i]
|
||||
}
|
||||
|
||||
// 可以嵌套的Rest http server mux
|
||||
type RestMux struct {
|
||||
Path string
|
||||
imux *http.ServeMux
|
||||
rmuxPaths []string
|
||||
routes Routes
|
||||
middlewares []Middleware
|
||||
}
|
||||
|
||||
|
@ -37,27 +101,39 @@ func (mux *RestMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
_, has := lo.Find(mux.rmuxPaths, func(s string) bool {
|
||||
return strings.HasPrefix(newRequest.URL.Path, s)
|
||||
})
|
||||
if has {
|
||||
mux.imux.ServeHTTP(w, newRequest)
|
||||
return
|
||||
// _, has := lo.Find(mux.rmuxPaths, func(s string) bool {
|
||||
// return strings.HasPrefix(newRequest.URL.Path, s)
|
||||
// })
|
||||
// if has {
|
||||
// mux.imux.ServeHTTP(w, newRequest)
|
||||
// return
|
||||
// }
|
||||
|
||||
// 根据r 从routes中找到匹配的路由
|
||||
for _, route := range mux.routes {
|
||||
if route.Match(newRequest) {
|
||||
route.ServeHTTP(w, newRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
// newRequest.URL.Path = "/" + strings.ToLower(newRequest.Method) + newRequest.URL.Path
|
||||
// newRequest.RequestURI = "/" + strings.ToLower(newRequest.Method) + newRequest.RequestURI
|
||||
// h, _ := mux.imux.Handler(newRequest)
|
||||
|
||||
newRequest.URL.Path = "/" + strings.ToLower(newRequest.Method) + newRequest.URL.Path
|
||||
newRequest.RequestURI = "/" + strings.ToLower(newRequest.Method) + newRequest.RequestURI
|
||||
h, _ := mux.imux.Handler(newRequest)
|
||||
|
||||
h.ServeHTTP(w, newRequest)
|
||||
// h.ServeHTTP(w, newRequest)
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
||||
func (mux *RestMux) HandleFunc(method string, path string, f func(http.ResponseWriter, *http.Request)) {
|
||||
m := path
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
m = "/" + path
|
||||
r := &Route{
|
||||
Method: method,
|
||||
Path: path,
|
||||
Handle: f,
|
||||
Handler: nil,
|
||||
}
|
||||
mux.imux.HandleFunc("/"+strings.ToLower(method)+m, f)
|
||||
*r.matcher = ParseUrl(path)
|
||||
mux.routes = append(mux.routes, r)
|
||||
sort.Sort(mux.routes)
|
||||
}
|
||||
|
||||
func (mux *RestMux) Get(path string, f func(http.ResponseWriter, *http.Request)) {
|
||||
|
@ -90,14 +166,26 @@ func (mux *RestMux) HandleMux(nmux *RestMux) {
|
|||
if !strings.HasSuffix(p, "/") {
|
||||
p = p + "/"
|
||||
}
|
||||
mux.imux.Handle(p, http.StripPrefix(nmux.Path, nmux))
|
||||
mux.rmuxPaths = append(mux.rmuxPaths, nmux.Path)
|
||||
// mux.imux.Handle(p, http.StripPrefix(nmux.Path, nmux))
|
||||
// mux.rmuxPaths = append(mux.rmuxPaths, nmux.Path)
|
||||
r := &Route{
|
||||
Method: "",
|
||||
Path: p,
|
||||
Handle: nil,
|
||||
Handler: nmux,
|
||||
}
|
||||
r.matcher = &UrlParamMatcher{
|
||||
Params: []string{},
|
||||
Reg: nil,
|
||||
}
|
||||
sort.Sort(mux.routes)
|
||||
}
|
||||
|
||||
func NewRestMux(path string) *RestMux {
|
||||
return &RestMux{
|
||||
Path: path,
|
||||
imux: http.NewServeMux(),
|
||||
rmuxPaths: make([]string, 0),
|
||||
ret := &RestMux{
|
||||
Path: path,
|
||||
routes: Routes{},
|
||||
middlewares: []Middleware{},
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue