package req import ( "errors" "fmt" "net/http" "github.com/mafanr/juz/misc" "github.com/mafanr/g" "github.com/labstack/echo" ) type Request struct { Rid int64 Method string Params map[string]string Cookies []*http.Cookie Api *misc.API DebugOn bool ClientIP string Url string BwStrategy *misc.BwStrategy RetryStrategy *misc.RetryStrategy TrafficStrategy *misc.TrafficStrategy } func (r *Request) String() string { return fmt.Sprintf("method: %s,params: %v, api: %v, client_ip: %s", r.Method, r.Params, *r.Api, r.ClientIP) } func Parse(c echo.Context) (*Request, int, error) { r := &Request{ Rid: c.Get("rid").(int64), Params: make(map[string]string), } // 解析参数 ps, _ := c.FormParams() for k, v := range ps { // debug参数不透传 if k == g.DEBUG_PARAM { if v[0] == "true" { r.DebugOn = true } } else { r.Params[k] = v[0] } } // 解析cookie r.Cookies = c.Cookies() r.ClientIP = c.RealIP() r.Method = c.Request().Method var apiName string var version string // 判断是路径映射还是api映射 uri := c.Request().URL.Path if uri == "/service/api" { apiName = r.Params["service_id"] if apiName == "" { //新网关使用以下参数'api_name' apiName = r.Params["api_name"] if apiName == "" { return r, http.StatusBadRequest, errors.New("api_name not founded") } } } else { apiName = uri } version = r.Params["api_version"] if version == "" { // 如果没有传version,就默认为版本1 version = "1" } apiID := apiName + ".v" + version // 获取api信息 apiI, ok := misc.Apis.Load(apiID) if !ok { return r, http.StatusBadRequest, errors.New("api id not exist") } r.Api = apiI.(*misc.API) // 生成策略 strategy(r) // 获取url if r.Api.AddrType == misc.ADDR_URL { // direct url r.Url = r.Api.BackendAddr } else { // get url from etcd s := g.GetServer(r.Api.BackendAddr) if s == nil { return r, http.StatusServiceUnavailable, errors.New(g.NoServerAvailableE) } r.Url = "http://" + s.IP + r.Api.BackendURI } return r, 0, nil } func strategy(r *Request) { // 设置策略停用时的默认值 r.BwStrategy = &misc.BwStrategy{ Type: 0, } if r.Api.BwStrategy != 0 { s1, ok := misc.Strategies.Load(r.Api.BwStrategy) if ok { s := s1.(*misc.Strategy) if s.Status == misc.STRATEGY_ON { r.BwStrategy = s.DetailContent.(*misc.BwStrategy) } } } // 设置策略停用时的默认值 r.RetryStrategy = &misc.RetryStrategy{ ReqTimeout: misc.REQ_TIMEOUT, RetryTimes: misc.RETRY_TIMES, RetryInterval: misc.RETRY_INTERVAL, } if r.Api.RetryStrategy != 0 { s1, ok := misc.Strategies.Load(r.Api.RetryStrategy) if ok { s := s1.(*misc.Strategy) if s.Status == misc.STRATEGY_ON { r.RetryStrategy = s.DetailContent.(*misc.RetryStrategy) } } } // 设置策略停用时的默认值 r.TrafficStrategy = &misc.TrafficStrategy{ QPS: misc.STRATEGY_NO_LIMIT, Concurrent: misc.STRATEGY_NO_LIMIT, Param: "", } if r.Api.TrafficStrategy != 0 { s1, ok := misc.Strategies.Load(r.Api.TrafficStrategy) if ok { s := s1.(*misc.Strategy) if s.Status == misc.STRATEGY_ON { r.TrafficStrategy = s.DetailContent.(*misc.TrafficStrategy) } } } }