package CheckHandler import ( "fmt" "github.com/gin-gonic/gin" "strconv" "strings" ) //在注释标签中声明的标识字符串:X-LengthLimit var lengthLimit = "x-lengthlimit" //形成一个map,用于O(1)速度获取到一个接口是不是需要进行判断拦截,注意,一个接口可以存在post+get两种形式,所以map里面是一个数组,需要遍历 var lengthLimitMap = make(map[string][]lengthLimitStruct) //长度限制的map,以string为key(key的命名是接口名+"_get" 或者 接口名+"_post"),里面是lengthLimitStruct形式的数组 type lengthLimitStruct struct { parameterName string intRange string httpType string must bool } /** 功能:初始化长度限制字典 */ func lengthLimitInit(inter interface{}) map[string][]lengthLimitStruct { //参数检查器 m := inter.(map[string]interface{}) n := m["paths"].(map[string]interface{}) for k, v := range n { t := v.(map[string]interface{}) //参数长度检查器 var d map[string]interface{} if t["get"] != nil { lengthLimitaddToMap(t, d, k, "get") } if t["post"] != nil { lengthLimitaddToMap(t, d, k, "post") } } return lengthLimitMap } /** 功能:功能函数,添当前的检查字典里 */ func lengthLimitaddToMap(t map[string]interface{}, d map[string]interface{}, k string, httpType string) { var lengthLimitArray []lengthLimitStruct d = t[httpType].(map[string]interface{}) if d != nil && d[lengthLimit] != nil { for _, value := range d[lengthLimit].([]interface{}) { c := value.(map[string]interface{}) for k1, v1 := range c { var t lengthLimitStruct t.parameterName = k1 t.intRange = v1.(string) t.httpType = httpType //此参数是否为必填写项 for _, v2 := range d["parameters"].([]interface{}) { c2 := v2.(map[string]interface{}) for k2, v2 := range c2 { if k2 == "required" { t.must = v2.(bool) //标识是否是必须项 } } } lengthLimitArray = append(lengthLimitArray, t) } } lengthLimitMap[k+"_"+httpType] = lengthLimitArray } } /** 功能:检查字符串长度是否合法 作者:黄海 时间:2020-03-17 */ func lengthLimitIsLegal(c *gin.Context, interName string) (bool, ResultStruct) { var resultStruct ResultStruct //接口传入的请求方式:get?post? codeHttpType := strings.ToLower(c.Request.Method) //1、如果此接口地址需要进行参数长度检查 if lengthLimitMap[interName+"_"+codeHttpType] != nil { resultStruct.InterfaceName = interName arr := lengthLimitMap[interName+"_"+codeHttpType] //遍历arr for i := 0; i < len(arr); i++ { parameterName := arr[i].parameterName resultStruct.Parameter = arr[i].parameterName intRange := arr[i].intRange httpType := arr[i].httpType var p string if httpType == "get" { p = c.Query(parameterName) } else { p = c.PostForm(parameterName) } //为空,不需要检查,通过 if p == "" && !arr[i].must { return true, resultStruct } //为空,需要检查,禁止 if p == "" && arr[i].must{ resultStruct.Message = "参数没有找到!" return false, resultStruct } var nowInt int var err error //如果非空,检查是否为整数 nowInt = len(p) //检查是不是在符合的检查范围内 var rangeArray = strings.Split(intRange, ",") if len(rangeArray) != 2 { resultStruct.HttpType = httpType resultStruct.Message = "注释声明错误,不是两个以逗号分隔的数字,请研发人员检查!" return false, resultStruct } var startStr = rangeArray[0] var endStr = rangeArray[1] var startInt int var stopInt int if startInt, err = strconv.Atoi(startStr); err != nil { resultStruct.HttpType = httpType resultStruct.Message = "起始值无法转化为整数!" return false, resultStruct } if stopInt, err = strconv.Atoi(endStr); err != nil { resultStruct.HttpType = httpType resultStruct.Message = "终止值无法转化为整数!" return false, resultStruct } if stopInt < startInt { resultStruct.HttpType = httpType resultStruct.Message = "停止值小于起始佶,请研发人员检查!" return false, resultStruct } if nowInt < startInt || nowInt > stopInt { resultStruct.HttpType = httpType resultStruct.Message = fmt.Sprintf("不在规定的长度范围内!要求%d-%d,目前参数值:%d", startInt, stopInt, nowInt) return false, resultStruct } } } return true, resultStruct }