goProject/.svn/pristine/bf/bf8bed91ae6e4e864c464aeb7699d8ca58ca11ad.svn-base
2025-01-06 16:21:36 +08:00

354 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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),
}
}