1 Star 1 Fork 24

hequan / go-restful-api

forked from konyshe / gogo 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
HTTPRouterHandler.go 3.66 KB
一键复制 编辑 原始数据 按行查看 历史
konyshe 提交于 2018-06-29 08:49 . ctx.GetW() ==> ctx.GetResponseWriter()
package gogo
import (
"fmt"
"net/http"
"strings"
"sync"
)
type muxEntry struct {
h httpProcFunc
pattern string
}
type imuxEntry struct {
h httpProcFunc
pattern string
urlParams []string
}
// httpRouterHandler 保存注册函数的地方
type httpRouterHandler struct {
mu sync.RWMutex
//特殊STATE匹配
sm map[int]muxEntry
//固定特征的URL匹配
//map["GET"/"POST"][pattern]muxEntry
gm map[string]map[string]muxEntry
//含有":"的智能URL匹配
//map["GET"/"POST"][]imuxEntry
im map[string][]imuxEntry
hosts bool // whether any patterns contain hostnames
}
func (mux *httpRouterHandler) serveHTTPStatus(status int, w http.ResponseWriter, r *http.Request) {
ctx := &HTTPContext{w: w, r: r}
if v, ok := mux.sm[status]; ok {
v.h.ServeHTTP(ctx)
}
}
// ServeHTTP 官方HTTP触发入口
func (mux *httpRouterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if v, ok := mux.gm[r.Method][r.URL.Path]; ok {
ctx := &HTTPContext{w: w, r: r}
v.h.ServeHTTP(ctx)
return
}
for _, v := range mux.im[r.Method] {
if strings.HasPrefix(r.URL.Path, v.pattern) {
urlParams := strings.Split(string([]byte(r.URL.Path)[len(v.pattern)+1:]), "/")
if len(urlParams) == len(v.urlParams) {
extURLParams := make(map[string]string)
foundSuss := true
for urlParamsID, urlParamsValue := range urlParams {
if strings.HasPrefix(v.urlParams[urlParamsID], ":") {
extURLParams[v.urlParams[urlParamsID]] = urlParamsValue
} else if urlParamsValue != v.urlParams[urlParamsID] {
foundSuss = false
break
}
}
if foundSuss {
ctx := &HTTPContext{w: w, r: r, urlParams: extURLParams}
v.h.ServeHTTP(ctx)
return
}
}
}
}
mux.serveHTTPStatus(http.StatusNotFound, w, r)
}
// RegHTTPProcFunc 注册固定URL、解析URL函数
// method string: 请求方式,POST、GET、PUT、DELETE等
// pattern string:触发路径
// handler httpProcFunc: 触发函数
func (mux *httpRouterHandler) RegHTTPProcFunc(method, pattern string, handler httpProcFunc) {
mux.mu.Lock()
defer mux.mu.Unlock()
if pattern == "" {
panic("http: invalid pattern")
}
if handler == nil {
panic("http: nil handler")
}
if _, exist := mux.gm[pattern]; exist {
panic("http: multiple registrations for " + pattern)
}
if _, exist := mux.im[pattern]; exist {
panic("http: multiple registrations for " + pattern)
}
if mux.gm == nil {
mux.gm = make(map[string]map[string]muxEntry)
}
if mux.gm[method] == nil {
mux.gm[method] = make(map[string]muxEntry)
}
if mux.im == nil {
mux.im = make(map[string][]imuxEntry)
}
if mux.im[method] == nil {
mux.im[method] = []imuxEntry{}
}
istart := strings.Index(pattern, "/:")
if istart == -1 {
mux.gm[method][pattern] = muxEntry{h: handler, pattern: pattern}
} else {
if istart <= 1 {
fmt.Println(pattern + "错误,请不要以\\:开头!")
} else {
ipattern := string([]byte(pattern)[:istart])
urlParams := strings.Split(string([]byte(pattern)[istart+1:]), "/")
mux.im[method] = append(mux.im[method], imuxEntry{h: handler, urlParams: urlParams, pattern: ipattern})
}
}
if pattern[0] != '/' {
mux.hosts = true
}
}
// RegHTTPStatusFunc 注册指定HTTP状态触发的函数
// status int: HTTP状态, 参考net\http\status.go
// handler httpProcFunc: 触发函数
func (mux *httpRouterHandler) RegHTTPStatusFunc(status int, handler httpProcFunc) {
mux.mu.Lock()
defer mux.mu.Unlock()
if mux.sm == nil {
mux.sm = make(map[int]muxEntry)
}
mux.sm[status] = muxEntry{h: handler, pattern: "404"}
}
Go
1
https://gitee.com/hequan2020/go-restful-api.git
git@gitee.com:hequan2020/go-restful-api.git
hequan2020
go-restful-api
go-restful-api
master

搜索帮助