You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
3.2 KiB

7 years ago
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
7 years ago
Url string
7 years ago
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)
}
7 years ago
func Parse(c echo.Context) (*Request, int, error) {
7 years ago
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 == "" {
7 years ago
return r, http.StatusBadRequest, errors.New("api_name not founded")
7 years ago
}
}
} 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 {
7 years ago
return r, http.StatusBadRequest, errors.New("api id not exist")
7 years ago
}
r.Api = apiI.(*misc.API)
// 生成策略
strategy(r)
7 years ago
// 获取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
7 years ago
}
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)
}
}
}
}