goProject/.svn/pristine/bf/bf8bed91ae6e4e864c464aeb7699d8ca58ca11ad.svn-base

354 lines
10 KiB
Plaintext
Raw Normal View History

2025-01-06 16:21:36 +08:00
package webServer
import (
"fmt"
"net/http"
"regexp"
"strings"
"time"
"goutil/logUtil"
"goutil/typeUtil"
)
var (
defaultPageMap = make(map[string]bool)
)
func init() {
defaultPageMap["/"] = true
defaultPageMap["/favicon.ico"] = true
}
// web服务对象
type WebServer struct {
// 所有对外提供的处理器集合
handlerMap map[string]*handler
// 需要应用的Header集合
headerMap map[string]string
// 指定的HTTP请求方法如果不指定则任意方法均有效
specifiedMethod string
// 当HTTP请求方法无效时调用的处理器
invalidMethodHandler func(*Context)
// 默认页的处理器(默认页指的是/或/favicon.ico通常是被负载均衡器调用或在浏览器中直接访问而不会被程序调用
defaultPageHandler func(*Context)
// 未找到指定的回调时的处理器通常是因为该url是可变的而不是固定的
notFoundPageHandler func(*Context)
// 未处理的异常处理函数
unHandledPanicHandler func(context *Context, errObj interface{})
// ifDelegate:是否经过负责均衡中转经过负载均衡中转后Request的地址需要从Header获取
ifDelegate bool
// 在Debug模式下是否需要验证IP地址默认情况下不验证
ifCheckIPWhenDebug bool
// 当IP无效时调用的处理器
ipInvalidHandler func(*Context)
// 用于检测参数是否有效的处理器
paramCheckHandler func(typeUtil.MapData, []string, []string) ([]string, []string, bool)
// 当检测到参数无效时调用的处理器
paramInvalidHandler func(*Context, []string, []string)
// 处理请求数据的处理器(例如压缩、解密等)
requestDataHandler func(*Context, []byte) ([]byte, error)
// 处理响应数据的处理器(例如压缩、加密等)
responseDataHandler func(*Context, []byte) ([]byte, error)
// 请求执行时间的处理器
executeTimeHandler func(*Context)
}
// 注册API
// path注册的访问路径
// callback回调方法
// configObjHandler配置对象
func (this *WebServer) RegisterHandler(path string, handlerFuncObj handlerFunc, configObj *HandlerConfig) {
// 判断是否已经注册过,避免命名重复
if _, exist := this.handlerMap[path]; exist {
panic(fmt.Sprintf("%s has been registered, please try a new path", path))
}
this.handlerMap[path] = newHandler(path, handlerFuncObj, configObj)
}
// 注册回调-增加用户自定义数据
func (this *WebServer) RegisterHandlerWithUserData(path string, handlerFuncObj handlerFunc, configObj *HandlerConfig, userData interface{}) {
// 判断是否已经注册过,避免命名重复
if _, exist := this.handlerMap[path]; exist {
panic(fmt.Sprintf("%s has been registered, please try a new path", path))
}
handler := newHandler(path, handlerFuncObj, configObj)
handler.userData = userData
this.handlerMap[path] = handler
}
// 注册正则表式路径API
// path注册的访问路径
// callback回调方法
// configObjHandler配置对象
func (this *WebServer) RegisterRegexHandler(path string, handlerFuncObj handlerFunc, configObj *HandlerConfig) {
// 判断是否已经注册过,避免命名重复
if _, exist := this.handlerMap[path]; exist {
panic(fmt.Sprintf("%s has been registered, please try a new path", path))
}
handler := newHandler(path, handlerFuncObj, configObj)
handler.regex = true
this.handlerMap[path] = handler
}
// 注册正则回调-增加用户自定义数据
func (this *WebServer) RegisterRegexHandlerWithUserData(path string, handlerFuncObj handlerFunc, configObj *HandlerConfig, userData interface{}) {
// 判断是否已经注册过,避免命名重复
if _, exist := this.handlerMap[path]; exist {
panic(fmt.Sprintf("%s has been registered, please try a new path", path))
}
handler := newHandler(path, handlerFuncObj, configObj)
handler.userData = userData
handler.regex = true
this.handlerMap[path] = handler
}
// 获取请求方法
// path:方法名称
// 返回值:
// 请求方法
// 是否存在
func (this *WebServer) getHandler(path string) (handlerObj *handler, exist bool) {
handlerObj, exist = this.handlerMap[path]
if !exist {
for _, handler := range this.handlerMap {
if handler.regex {
match, _ := regexp.MatchString(handler.path, path)
if match {
return handler, true
}
}
}
}
return
}
// 设定Http Header信息
func (this *WebServer) SetHeader(header map[string]string) {
this.headerMap = header
}
// 处理Http Header信息
func (this *WebServer) handleHeader(context *Context) {
if this.headerMap != nil && len(this.headerMap) > 0 {
for k, v := range this.headerMap {
context.responseWriter.Header().Set(k, v)
}
}
}
// 设定HTTP请求方法
func (this *WebServer) SetMethod(method string) {
this.specifiedMethod = method
}
// 设定当HTTP请求方法无效时调用的处理器
func (this *WebServer) SetInvalidMethodHandler(handler func(*Context)) {
this.invalidMethodHandler = handler
}
// 处理HTTP请求方法
// 返回值
// isTerminate:是否终止本次请求
func (this *WebServer) handleMethod(context *Context) (isTerminate bool) {
if this.specifiedMethod != "" {
if context.request.Method != this.specifiedMethod {
if this.invalidMethodHandler != nil {
this.invalidMethodHandler(context)
} else {
http.Error(context.responseWriter, fmt.Sprintf("Expected %s Method", this.specifiedMethod), 406)
}
isTerminate = true
}
}
return
}
// 设定默认页的处理器
func (this *WebServer) SetDefaultPageHandler(handler func(*Context)) {
this.defaultPageHandler = handler
}
// 处理默认页
// 返回值
// isTerminate:是否终止本次请求
func (this *WebServer) handleDefaultPage(context *Context) (isTerminate bool) {
// 首页进行特别处理
if _, exist := defaultPageMap[context.GetRequestPath()]; exist {
if this.defaultPageHandler != nil {
this.defaultPageHandler(context)
} else {
context.WriteString("Welcome to home page.")
}
isTerminate = true
}
return
}
// 设定未找到指定的回调时的处理器
func (this *WebServer) SetNotFoundPageHandler(handler func(*Context)) {
this.notFoundPageHandler = handler
}
// 设置异常处理函数(默认只会记录在文件)
func (this *WebServer) SetUnHandledPanicHandler(handler func(context *Context, errObj interface{})) {
this.unHandledPanicHandler = handler
}
// 设定在Debug模式下是否需要验证IP地址
func (this *WebServer) SetIfCheckIPWhenDebug(value bool) {
this.ifCheckIPWhenDebug = value
}
// 设定当IP无效时调用的处理器
func (this *WebServer) SetIPInvalidHandler(handler func(*Context)) {
this.ipInvalidHandler = handler
}
// 设定用于检测参数是否有效的处理器
func (this *WebServer) SetParamCheckHandler(handler func(typeUtil.MapData, []string, []string) ([]string, []string, bool)) {
this.paramCheckHandler = handler
}
// 设定当检测到参数无效时调用的处理器
func (this *WebServer) SetParamInvalidHandler(handler func(*Context, []string, []string)) {
this.paramInvalidHandler = handler
}
// 设定处理请求数据的处理器(例如压缩、解密等)
func (this *WebServer) SetRequestDataHandler(handler func(*Context, []byte) ([]byte, error)) {
this.requestDataHandler = handler
}
// 设定处理响应数据的处理器(例如压缩、加密等)
func (this *WebServer) SetResponseDataHandler(handler func(*Context, []byte) ([]byte, error)) {
this.responseDataHandler = handler
}
// 设定请求执行时间的处理器
func (this *WebServer) SetExecuteTimeHandler(handler func(*Context)) {
this.executeTimeHandler = handler
}
// 处理请求执行时间逻辑
func (this *WebServer) handleExecuteTime(context *Context) {
if this.executeTimeHandler != nil {
this.executeTimeHandler(context)
}
}
// 设置WebServer请求是否经过了负载均衡中转
func (this *WebServer) SetIfDelegate(ifDelegate bool) {
this.ifDelegate = ifDelegate
}
// http应答处理
// responseWriter:应答对象
// request:请求对象
func (this *WebServer) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {
// 构造上下文对象
context := newContext(request, responseWriter, this.requestDataHandler, this.responseDataHandler, this.ifDelegate)
defer func() {
if r := recover(); r != nil {
if this.unHandledPanicHandler != nil {
this.unHandledPanicHandler(context, r)
} else {
logUtil.LogUnknownError(r)
}
}
}()
// 处理Http Header信息
this.handleHeader(context)
// 处理默认页
if this.handleDefaultPage(context) {
return
}
// 处理返回值信息
defer func() {
// 处理请求执行时间逻辑
this.handleExecuteTime(context)
}()
// 处理请求方法
if this.handleMethod(context) {
return
}
// 根据路径选择不同的处理方法
var handlerObj *handler
var exist bool
if handlerObj, exist = this.getHandler(context.GetRequestPath()); !exist {
if this.notFoundPageHandler != nil {
this.notFoundPageHandler(context)
} else {
http.Error(context.responseWriter, "访问的页面不存在", 404)
}
return
}
// 将用户自定义数据通过Context传入回调
context.userData = handlerObj.userData
// Check IP
if handlerObj.checkIP(context, this.ifCheckIPWhenDebug) == false {
if this.ipInvalidHandler != nil {
this.ipInvalidHandler(context)
} else {
http.Error(context.responseWriter, "你的IP不允许访问请联系管理员", 401)
}
return
}
// Check Param
if missParamList, emptyParamList, valid := handlerObj.checkParam(context, this.specifiedMethod, this.paramCheckHandler); valid == false {
if this.paramInvalidHandler != nil {
this.paramInvalidHandler(context, missParamList, emptyParamList)
} else {
if missParamList != nil && len(missParamList) > 0 {
http.Error(context.responseWriter, fmt.Sprintf("你的参数不正确,请检查,缺少以下参数:%s", strings.Join(missParamList, ",")), 500)
} else {
http.Error(context.responseWriter, fmt.Sprintf("你的参数不正确,请检查,以下参数为空:%s", strings.Join(emptyParamList, ",")), 500)
}
}
return
}
// Call Function
handlerObj.funcObj(context)
context.EndTime = time.Now()
}
// 新建WebServer对象
// isCheckIP:该属性已丢弃,可以任意赋值
func NewWebServer(isCheckIP bool) *WebServer {
return &WebServer{
handlerMap: make(map[string]*handler),
headerMap: make(map[string]string),
}
}