package useragent import ( "net/url" "strings" "videoweb/pub/common/enum/consts" "videoweb/pub/common/log" "videoweb/pub/pubdef" "github.com/gin-gonic/gin" ) type UA struct { DevID string DevType string SysType pubdef.SysType Ver string BuildID string UserAgent string SDKCommon *SDKCommonFields // SDK 公共参数独立保存,不能与原业务 UA 字段混用。 RequestPath string // 仅用于定位埋点参数缺失的业务接口。 } func IsH5(sysType pubdef.SysType) bool { return sysType.IsH5() } func (s UA) IsH5() bool { return s.SysType.IsH5() } func UserAgent(c *gin.Context) { var uastr string ua := UA{RequestPath: c.FullPath()} var sdkErr error ua.SDKCommon, sdkErr = ParseSDKCommonHeader(c.GetHeader(SDKCommonHeader)) if sdkErr != nil { log.Error("【SDK公共参数解析失败】UserAgent", log.Any("接口", ua.RequestPath), log.E(sdkErr)) } userAgent := c.GetHeader("X-User-Agent") //兼容H5 UserAgent if userAgent == "" { userAgent = c.Request.UserAgent() } ua.UserAgent = userAgent if userAgent != "" { // "BuildID=com.abc.Butterfly;SysType=h5;DevID=B9A00938-FE68-4686-9461-A365C7E5110D;Ver=0.0.1;DevType=iPhone;" decodeUa, err := url.QueryUnescape(userAgent) if err != nil { log.Warn("URLDecode user-agent error", log.Any("ua", userAgent)) uastr = userAgent } else { uastr = decodeUa } uas := strings.Split(uastr, ";") for _, v := range uas { vss := strings.Split(strings.TrimSpace(v), "=") if len(vss) < 2 { c.Set(consts.CtxUAH5, vss[0]) // log.Warn("user-agent miss", log.Any("ua", userAgent), log.Any("v", v)) continue } switch strings.TrimSpace(vss[0]) { case "DevID": ua.DevID = strings.TrimSpace(vss[1]) c.Set(consts.CtxDevId, ua.DevID) case "DevType": ua.DevType = strings.TrimSpace(vss[1]) c.Set(consts.CtxDevType, ua.DevType) case "SysType": input := strings.ToLower(strings.TrimSpace(vss[1])) switch { case strings.Contains(input, "h5_android"): ua.SysType = pubdef.ST_H5Android case strings.Contains(input, "h5_ios"): ua.SysType = pubdef.ST_H5IOS case strings.Contains(input, "h5_pc"): ua.SysType = pubdef.ST_H5PC case strings.Contains(input, "android"): ua.SysType = pubdef.ST_Android case strings.Contains(input, "ios"): ua.SysType = pubdef.ST_IOS case strings.Contains(input, "h5"): ua.SysType = pubdef.ST_H5 case strings.Contains(input, "pc"): ua.SysType = pubdef.ST_PC case strings.Contains(input, "light"): ua.SysType = pubdef.ST_Light case strings.Contains(input, "tg"): ua.SysType = pubdef.ST_TG case strings.Contains(input, "web"): ua.SysType = pubdef.ST_Web } // 存入 context 时用 string,保持 ctx.GetString 兼容 c.Set(consts.CtxSysType, string(ua.SysType)) case "Ver": ua.Ver = strings.TrimSpace(vss[1]) c.Set(consts.CtxVersion, ua.Ver) case "BuildID": ua.BuildID = strings.TrimSpace(vss[1]) c.Set(consts.CtxBuildId, ua.BuildID) default: log.Warn("user-agent unknown", log.Any("ua", userAgent)) } } } else { log.Warn("user-agent empty") } c.Set(consts.CtxUA, ua) }