2023-12-07 22:42:27 +08:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/samber/lo"
|
|
|
|
)
|
|
|
|
|
|
|
|
// 可以嵌套的Rest http server mux
|
|
|
|
type RestMux struct {
|
2023-12-11 18:15:29 +08:00
|
|
|
Path string
|
|
|
|
imux *http.ServeMux
|
|
|
|
rmuxPaths []string
|
|
|
|
middlewares []Middleware
|
2023-12-07 22:42:27 +08:00
|
|
|
}
|
|
|
|
|
2023-12-11 18:15:29 +08:00
|
|
|
func (mux *RestMux) Use(m Middleware) {
|
|
|
|
mux.middlewares = append(mux.middlewares, m)
|
|
|
|
}
|
2023-12-07 22:42:27 +08:00
|
|
|
func (mux *RestMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
2023-12-11 18:15:29 +08:00
|
|
|
canContinue := false
|
|
|
|
if len(mux.middlewares) > 0 {
|
|
|
|
for _, m := range mux.middlewares {
|
|
|
|
canContinue = false
|
|
|
|
m(w, r, func() { canContinue = true })
|
|
|
|
if !canContinue {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-08 22:02:36 +08:00
|
|
|
_, has := lo.Find(mux.rmuxPaths, func(s string) bool {
|
2023-12-07 22:42:27 +08:00
|
|
|
return strings.HasPrefix(r.URL.Path, s)
|
|
|
|
})
|
|
|
|
if has {
|
|
|
|
mux.imux.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
r.URL.Path = "/" + strings.ToLower(r.Method) + r.URL.Path
|
|
|
|
r.RequestURI = "/" + strings.ToLower(r.Method) + r.RequestURI
|
|
|
|
h, _ := mux.imux.Handler(r)
|
|
|
|
|
|
|
|
h.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mux *RestMux) HandleFunc(method string, path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
m := path
|
|
|
|
if !strings.HasPrefix(path, "/") {
|
|
|
|
m = "/" + path
|
|
|
|
}
|
|
|
|
mux.imux.HandleFunc("/"+strings.ToLower(method)+m, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mux *RestMux) Get(path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
mux.HandleFunc("GET", path, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mux *RestMux) Post(path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
mux.HandleFunc("POST", path, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mux *RestMux) Put(path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
mux.HandleFunc("PUT", path, f)
|
|
|
|
}
|
|
|
|
func (mux *RestMux) Delete(path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
mux.HandleFunc("DELETE", path, f)
|
|
|
|
}
|
|
|
|
func (mux *RestMux) Patch(path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
mux.HandleFunc("PATCH", path, f)
|
|
|
|
}
|
|
|
|
func (mux *RestMux) Head(path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
mux.HandleFunc("HEAD", path, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mux *RestMux) Option(path string, f func(http.ResponseWriter, *http.Request)) {
|
|
|
|
mux.HandleFunc("OPTION", path, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mux *RestMux) HandleMux(nmux *RestMux) {
|
|
|
|
p := nmux.Path
|
|
|
|
if !strings.HasSuffix(p, "/") {
|
|
|
|
p = p + "/"
|
|
|
|
}
|
|
|
|
mux.imux.Handle(p, http.StripPrefix(nmux.Path, nmux))
|
|
|
|
mux.rmuxPaths = append(mux.rmuxPaths, nmux.Path)
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRestMux(path string) *RestMux {
|
|
|
|
return &RestMux{
|
|
|
|
Path: path,
|
|
|
|
imux: http.NewServeMux(),
|
|
|
|
rmuxPaths: make([]string, 0),
|
|
|
|
}
|
|
|
|
}
|