Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

321 строка
9.4 KiB

  1. package request
  2. import (
  3. "fmt"
  4. "gitlab.ecloud.com/ecloud/ecloudsdkcore/consts"
  5. "gitlab.ecloud.com/ecloud/ecloudsdkcore/errs"
  6. "gitlab.ecloud.com/ecloud/ecloudsdkcore/param"
  7. "gitlab.ecloud.com/ecloud/ecloudsdkcore/position"
  8. "gitlab.ecloud.com/ecloud/ecloudsdkcore/utils"
  9. "reflect"
  10. "strings"
  11. )
  12. type HttpRequest struct {
  13. Method string `json:"method,omitempty"`
  14. Protocol string `json:"protocol,omitempty"`
  15. Url string `json:"url,omitempty"`
  16. Path string `json:"path,omitempty"`
  17. Action string `json:"action,omitempty"`
  18. Product string `json:"product,omitempty"`
  19. Version string `json:"version,omitempty"`
  20. SdkVersion string `json:"sdkVersion,omitempty"`
  21. Source string `json:"source,omitempty"`
  22. SecurityToken string `json:"securityToken,omitempty"`
  23. QueryString string `json:"queryString,omitempty"`
  24. ContentType string `json:"contentType,omitempty"`
  25. Endpoint string `json:"endpoint,omitempty"`
  26. Body interface{} `json:"body,omitempty"`
  27. PathParams map[string]string `json:"pathParams,omitempty"`
  28. QueryParams map[string]string `json:"queryParams,omitempty"`
  29. HeaderParams map[string]string `json:"headerParams,omitempty"`
  30. }
  31. type HttpRequestPosition string
  32. const (
  33. BODY HttpRequestPosition = "Body"
  34. QUERY HttpRequestPosition = "Query"
  35. PATH HttpRequestPosition = "Path"
  36. HEADER HttpRequestPosition = "Header"
  37. )
  38. func NewHttpRequest() *HttpRequest {
  39. return &HttpRequest{
  40. Method: "POST",
  41. QueryParams: make(map[string]string),
  42. HeaderParams: make(map[string]string),
  43. PathParams: make(map[string]string),
  44. ContentType: "application/json; charset=utf-8",
  45. }
  46. }
  47. func DefaultHttpRequest() *HttpRequest {
  48. return NewHttpRequest()
  49. }
  50. func (httpReq *HttpRequest) Reset() {
  51. httpReq.Action = ""
  52. httpReq.SecurityToken = ""
  53. httpReq.QueryParams = make(map[string]string)
  54. httpReq.HeaderParams = make(map[string]string)
  55. httpReq.PathParams = make(map[string]string)
  56. httpReq.Body = nil
  57. httpReq.Method = "POST"
  58. }
  59. func (httpReq *HttpRequest) BuildHeaderParams(headerParams map[string]string) {
  60. if httpReq.HeaderParams == nil {
  61. httpReq.HeaderParams = make(map[string]string)
  62. }
  63. for name, value := range headerParams {
  64. httpReq.HeaderParams[name] = value
  65. }
  66. }
  67. func (httpReq *HttpRequest) AddDefaultHeaders() error {
  68. if strings.HasSuffix(httpReq.Product, "inner") && utils.IsUnSet(httpReq.Source) {
  69. return errs.NewInvalidParameterError("the attribute named source in SDK config must not be null", nil)
  70. }
  71. if httpReq.HeaderParams == nil {
  72. httpReq.HeaderParams = make(map[string]string)
  73. }
  74. x := fmt.Sprintf("action:%s;product:%s;version:%s;sdkversion:%s;language:Golang;coreversion:1.0.5",
  75. httpReq.Action, httpReq.Product, httpReq.Version, httpReq.SdkVersion)
  76. if len(httpReq.Source) > 0 {
  77. x += fmt.Sprintf(";source:%s", httpReq.Source)
  78. }
  79. if len(httpReq.SecurityToken) > 0 {
  80. httpReq.HeaderParams["x-openapi-security-token"] = httpReq.SecurityToken
  81. }
  82. httpReq.HeaderParams["x-openapi-sdk"] = x
  83. httpReq.HeaderParams["User-Agent"] = "OpenAPI/2.0/Golang"
  84. return nil
  85. }
  86. func (httpReq *HttpRequest) BuildQueryParams(queryParams map[string]string) {
  87. if httpReq.QueryParams == nil {
  88. httpReq.QueryParams = make(map[string]string)
  89. }
  90. for name, value := range queryParams {
  91. httpReq.QueryParams[name] = value
  92. }
  93. }
  94. func (httpReq *HttpRequest) BuildPathParams(pathParams map[string]string) {
  95. if httpReq.PathParams == nil {
  96. httpReq.PathParams = make(map[string]string)
  97. }
  98. for name, value := range pathParams {
  99. httpReq.PathParams[name] = value
  100. }
  101. }
  102. func (httpReq *HttpRequest) BuildApiParams(params *param.Params, cm map[string]interface{}) error {
  103. if params == nil {
  104. return nil
  105. }
  106. if len(params.ContentType) > 0 {
  107. httpReq.ContentType = params.ContentType
  108. }
  109. if len(params.Method) > 0 {
  110. httpReq.Method = params.Method
  111. }
  112. if len(params.Protocol) > 0 {
  113. httpReq.Protocol = params.Protocol
  114. }
  115. ignoreGateway := cm["IgnoreGateway"].(*bool)
  116. if utils.BoolValue(ignoreGateway) {
  117. httpReq.Path = params.Uri
  118. } else {
  119. httpReq.Path = params.GatewayUri
  120. }
  121. if len(params.Action) > 0 {
  122. httpReq.Action = params.Action
  123. }
  124. if utils.IsSet(cm["Source"]) {
  125. httpReq.Source = *cm["Source"].(*string)
  126. }
  127. if httpReq.PathParams != nil && len(httpReq.PathParams) > 0 {
  128. httpReq.BuildPathParamsString()
  129. }
  130. if utils.IsSet(cm["RegionId"]) {
  131. httpReq.AddHeaders(map[string]string{"Region-Id": utils.StringValue(cm["RegionId"].(*string))})
  132. } else {
  133. if utils.IsSet(cm["PoolId"]) {
  134. httpReq.AddHeaders(map[string]string{"Pool-Id": utils.StringValue(cm["PoolId"].(*string))})
  135. }
  136. }
  137. if utils.IsSet(cm["SecurityToken"]) {
  138. httpReq.SecurityToken = utils.StringValue(cm["SecurityToken"].(*string))
  139. }
  140. err := httpReq.AddDefaultHeaders()
  141. if err != nil {
  142. return err
  143. }
  144. if utils.IsSet(cm["GlobalQueryParams"]) && len(cm["GlobalQueryParams"].(map[string]string)) > 0 {
  145. httpReq.BuildQueryParams(cm["GlobalQueryParams"].(map[string]string))
  146. }
  147. if utils.IsSet(cm["GlobalHeaderParams"]) && len(cm["GlobalHeaderParams"].(map[string]string)) > 0 {
  148. httpReq.BuildHeaderParams(cm["GlobalHeaderParams"].(map[string]string))
  149. }
  150. if utils.IsSet(cm["RuntimeHeaderParams"]) && len(cm["RuntimeHeaderParams"].(map[string]string)) > 0 {
  151. httpReq.BuildHeaderParams(cm["RuntimeHeaderParams"].(map[string]string))
  152. }
  153. if !utils.BoolValue(cm["CentralTransportEnabled"].(*bool)) && len(httpReq.Endpoint) > 0 {
  154. httpReq.Url = httpReq.Endpoint
  155. } else {
  156. httpReq.Url = utils.DefaultEndpoint
  157. }
  158. if utils.IsSet(cm["HttpProxy"]) {
  159. httpReq.Url = utils.StringValue(cm["HttpProxy"].(*string))
  160. }
  161. if utils.IsSet(cm["HttpsProxy"]) {
  162. httpReq.Url = utils.StringValue(cm["HttpsProxy"].(*string))
  163. }
  164. return nil
  165. }
  166. func (httpReq *HttpRequest) BuildFinalUrl() {
  167. url := httpReq.Url
  168. if len(url) == 0 {
  169. return
  170. }
  171. protocol := httpReq.Protocol
  172. if len(protocol) > 0 &&
  173. !strings.HasPrefix(url, "http") &&
  174. !strings.HasPrefix(url, "https") {
  175. url = protocol + "://" + url
  176. }
  177. path := httpReq.Path
  178. if len(path) > 0 {
  179. url = url + path
  180. }
  181. queryString := httpReq.QueryString
  182. if len(queryString) > 0 {
  183. url = url + queryString
  184. }
  185. httpReq.Url = url
  186. }
  187. func (httpReq *HttpRequest) BuildPathParamsString() {
  188. for name, value := range httpReq.PathParams {
  189. httpReq.Path = strings.ReplaceAll(httpReq.Path, fmt.Sprintf("{%s}", name), value)
  190. }
  191. if !strings.HasPrefix(httpReq.Path, "/") {
  192. httpReq.Path = "/" + httpReq.Path
  193. }
  194. if strings.HasSuffix(httpReq.Path, "/") {
  195. httpReq.Path = httpReq.Path[0 : len(httpReq.Path)-1]
  196. }
  197. }
  198. func (httpReq *HttpRequest) BuildQueryParamsString() {
  199. build := strings.Builder{}
  200. paramCount := len(httpReq.QueryParams)
  201. for name, value := range httpReq.QueryParams {
  202. build.WriteString(utils.PercentEncode(name))
  203. build.WriteString("=")
  204. build.WriteString(utils.PercentEncode(value))
  205. paramCount--
  206. if paramCount > 0 {
  207. build.WriteString("&")
  208. }
  209. }
  210. httpReq.QueryString = build.String()
  211. }
  212. func (httpReq *HttpRequest) ConvertRequest(request interface{}) {
  213. if request == nil {
  214. return
  215. }
  216. reqType := reflect.TypeOf(request)
  217. if reqType.Kind() == reflect.Ptr {
  218. reqType = reqType.Elem()
  219. }
  220. reqValue := reflect.ValueOf(request)
  221. if reqValue.Kind() == reflect.Ptr {
  222. reqValue = reqValue.Elem()
  223. }
  224. var flag = false
  225. for i := 0; i < reqType.NumField(); i++ {
  226. fieldType := reqType.Field(i)
  227. value := reqValue.FieldByName(fieldType.Name)
  228. if value.Kind() == reflect.Ptr {
  229. if value.IsNil() {
  230. continue
  231. }
  232. value = value.Elem()
  233. }
  234. propertyType := fieldType.Type
  235. if propertyType.Kind() == reflect.Ptr {
  236. propertyType = propertyType.Elem()
  237. }
  238. _, flag = propertyType.FieldByName(string(BODY))
  239. if flag {
  240. httpReq.Body = value.Interface()
  241. continue
  242. }
  243. _, flag = propertyType.FieldByName(string(HEADER))
  244. if flag {
  245. httpReq.BuildHeaderParams(utils.StructToMap(value.Interface(), ignorePositionField))
  246. continue
  247. }
  248. _, flag = propertyType.FieldByName(string(QUERY))
  249. if flag {
  250. httpReq.BuildQueryParams(utils.StructToMap(value.Interface(), ignorePositionField))
  251. continue
  252. }
  253. _, flag = propertyType.FieldByName(string(PATH))
  254. if flag {
  255. httpReq.BuildPathParams(utils.StructToMap(value.Interface(), ignorePositionField))
  256. continue
  257. }
  258. }
  259. }
  260. func (httpReq *HttpRequest) AddHeaders(headers map[string]string) {
  261. if httpReq.HeaderParams == nil {
  262. httpReq.HeaderParams = map[string]string{}
  263. }
  264. for name, value := range headers {
  265. httpReq.HeaderParams[name] = value
  266. }
  267. }
  268. var _typeOfHeader = reflect.TypeOf(position.Header{})
  269. var _typeOfBody = reflect.TypeOf(position.Body{})
  270. var _typeOfQuery = reflect.TypeOf(position.Query{})
  271. var _typeOfPath = reflect.TypeOf(position.Path{})
  272. func ignorePositionField(obj interface{}, field reflect.StructField, value reflect.Value) bool {
  273. if utils.ValueIsEmpty(value) {
  274. return true
  275. }
  276. typeOfValue := value.Type()
  277. return typeOfValue == _typeOfBody || typeOfValue == _typeOfQuery ||
  278. typeOfValue == _typeOfHeader || typeOfValue == _typeOfPath
  279. }
  280. func (httpReq *HttpRequest) ConvertQueryParamsFromPath() {
  281. if !strings.Contains(httpReq.Path, consts.QueryStartSymbol) {
  282. return
  283. }
  284. pathArray := strings.Split(httpReq.Path, consts.QueryStartSymbol)
  285. paramArray := strings.Split(pathArray[1], consts.ParameterSeparator)
  286. for _, param := range paramArray {
  287. if len(param) == 0 {
  288. continue
  289. }
  290. queryParamArray := strings.Split(param, consts.QuerySeparator)
  291. if len(queryParamArray) != 2 {
  292. continue
  293. }
  294. httpReq.QueryParams[queryParamArray[0]] = queryParamArray[1]
  295. }
  296. httpReq.Path = pathArray[0]
  297. }