acs_request.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. */
  14. package requests
  15. import (
  16. "fmt"
  17. "io"
  18. "reflect"
  19. "strconv"
  20. "strings"
  21. "time"
  22. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
  23. )
  24. const (
  25. RPC = "RPC"
  26. ROA = "ROA"
  27. HTTP = "HTTP"
  28. HTTPS = "HTTPS"
  29. DefaultHttpPort = "80"
  30. GET = "GET"
  31. PUT = "PUT"
  32. POST = "POST"
  33. DELETE = "DELETE"
  34. HEAD = "HEAD"
  35. OPTIONS = "OPTIONS"
  36. Json = "application/json"
  37. Xml = "application/xml"
  38. Raw = "application/octet-stream"
  39. Form = "application/x-www-form-urlencoded"
  40. Header = "Header"
  41. Query = "Query"
  42. Body = "Body"
  43. Path = "Path"
  44. HeaderSeparator = "\n"
  45. )
  46. // interface
  47. type AcsRequest interface {
  48. GetScheme() string
  49. GetMethod() string
  50. GetDomain() string
  51. GetPort() string
  52. GetRegionId() string
  53. GetHeaders() map[string]string
  54. GetQueryParams() map[string]string
  55. GetFormParams() map[string]string
  56. GetContent() []byte
  57. GetBodyReader() io.Reader
  58. GetStyle() string
  59. GetProduct() string
  60. GetVersion() string
  61. GetActionName() string
  62. GetAcceptFormat() string
  63. GetLocationServiceCode() string
  64. GetLocationEndpointType() string
  65. GetReadTimeout() time.Duration
  66. GetConnectTimeout() time.Duration
  67. SetReadTimeout(readTimeout time.Duration)
  68. SetConnectTimeout(connectTimeout time.Duration)
  69. SetHTTPSInsecure(isInsecure bool)
  70. GetHTTPSInsecure() *bool
  71. GetUserAgent() map[string]string
  72. SetStringToSign(stringToSign string)
  73. GetStringToSign() string
  74. SetDomain(domain string)
  75. SetContent(content []byte)
  76. SetScheme(scheme string)
  77. BuildUrl() string
  78. BuildQueries() string
  79. addHeaderParam(key, value string)
  80. addQueryParam(key, value string)
  81. addFormParam(key, value string)
  82. addPathParam(key, value string)
  83. }
  84. // base class
  85. type baseRequest struct {
  86. Scheme string
  87. Method string
  88. Domain string
  89. Port string
  90. RegionId string
  91. ReadTimeout time.Duration
  92. ConnectTimeout time.Duration
  93. isInsecure *bool
  94. userAgent map[string]string
  95. product string
  96. version string
  97. actionName string
  98. AcceptFormat string
  99. QueryParams map[string]string
  100. Headers map[string]string
  101. FormParams map[string]string
  102. Content []byte
  103. locationServiceCode string
  104. locationEndpointType string
  105. queries string
  106. stringToSign string
  107. }
  108. func (request *baseRequest) GetQueryParams() map[string]string {
  109. return request.QueryParams
  110. }
  111. func (request *baseRequest) GetFormParams() map[string]string {
  112. return request.FormParams
  113. }
  114. func (request *baseRequest) GetReadTimeout() time.Duration {
  115. return request.ReadTimeout
  116. }
  117. func (request *baseRequest) GetConnectTimeout() time.Duration {
  118. return request.ConnectTimeout
  119. }
  120. func (request *baseRequest) SetReadTimeout(readTimeout time.Duration) {
  121. request.ReadTimeout = readTimeout
  122. }
  123. func (request *baseRequest) SetConnectTimeout(connectTimeout time.Duration) {
  124. request.ConnectTimeout = connectTimeout
  125. }
  126. func (request *baseRequest) GetHTTPSInsecure() *bool {
  127. return request.isInsecure
  128. }
  129. func (request *baseRequest) SetHTTPSInsecure(isInsecure bool) {
  130. request.isInsecure = &isInsecure
  131. }
  132. func (request *baseRequest) GetContent() []byte {
  133. return request.Content
  134. }
  135. func (request *baseRequest) GetVersion() string {
  136. return request.version
  137. }
  138. func (request *baseRequest) GetActionName() string {
  139. return request.actionName
  140. }
  141. func (request *baseRequest) SetContent(content []byte) {
  142. request.Content = content
  143. }
  144. func (request *baseRequest) GetUserAgent() map[string]string {
  145. return request.userAgent
  146. }
  147. func (request *baseRequest) AppendUserAgent(key, value string) {
  148. newkey := true
  149. if request.userAgent == nil {
  150. request.userAgent = make(map[string]string)
  151. }
  152. if strings.ToLower(key) != "core" && strings.ToLower(key) != "go" {
  153. for tag, _ := range request.userAgent {
  154. if tag == key {
  155. request.userAgent[tag] = value
  156. newkey = false
  157. }
  158. }
  159. if newkey {
  160. request.userAgent[key] = value
  161. }
  162. }
  163. }
  164. func (request *baseRequest) addHeaderParam(key, value string) {
  165. request.Headers[key] = value
  166. }
  167. func (request *baseRequest) addQueryParam(key, value string) {
  168. request.QueryParams[key] = value
  169. }
  170. func (request *baseRequest) addFormParam(key, value string) {
  171. request.FormParams[key] = value
  172. }
  173. func (request *baseRequest) GetAcceptFormat() string {
  174. return request.AcceptFormat
  175. }
  176. func (request *baseRequest) GetLocationServiceCode() string {
  177. return request.locationServiceCode
  178. }
  179. func (request *baseRequest) GetLocationEndpointType() string {
  180. return request.locationEndpointType
  181. }
  182. func (request *baseRequest) GetProduct() string {
  183. return request.product
  184. }
  185. func (request *baseRequest) GetScheme() string {
  186. return request.Scheme
  187. }
  188. func (request *baseRequest) SetScheme(scheme string) {
  189. request.Scheme = scheme
  190. }
  191. func (request *baseRequest) GetMethod() string {
  192. return request.Method
  193. }
  194. func (request *baseRequest) GetDomain() string {
  195. return request.Domain
  196. }
  197. func (request *baseRequest) SetDomain(host string) {
  198. request.Domain = host
  199. }
  200. func (request *baseRequest) GetPort() string {
  201. return request.Port
  202. }
  203. func (request *baseRequest) GetRegionId() string {
  204. return request.RegionId
  205. }
  206. func (request *baseRequest) GetHeaders() map[string]string {
  207. return request.Headers
  208. }
  209. func (request *baseRequest) SetContentType(contentType string) {
  210. request.addHeaderParam("Content-Type", contentType)
  211. }
  212. func (request *baseRequest) GetContentType() (contentType string, contains bool) {
  213. contentType, contains = request.Headers["Content-Type"]
  214. return
  215. }
  216. func (request *baseRequest) SetStringToSign(stringToSign string) {
  217. request.stringToSign = stringToSign
  218. }
  219. func (request *baseRequest) GetStringToSign() string {
  220. return request.stringToSign
  221. }
  222. func defaultBaseRequest() (request *baseRequest) {
  223. request = &baseRequest{
  224. Scheme: "",
  225. AcceptFormat: "JSON",
  226. Method: GET,
  227. QueryParams: make(map[string]string),
  228. Headers: map[string]string{
  229. "x-sdk-client": "golang/1.0.0",
  230. "x-sdk-invoke-type": "normal",
  231. "Accept-Encoding": "identity",
  232. },
  233. FormParams: make(map[string]string),
  234. }
  235. return
  236. }
  237. func InitParams(request AcsRequest) (err error) {
  238. requestValue := reflect.ValueOf(request).Elem()
  239. err = flatRepeatedList(requestValue, request, "", "")
  240. return
  241. }
  242. func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, prefix string) (err error) {
  243. dataType := dataValue.Type()
  244. for i := 0; i < dataType.NumField(); i++ {
  245. field := dataType.Field(i)
  246. name, containsNameTag := field.Tag.Lookup("name")
  247. fieldPosition := position
  248. if fieldPosition == "" {
  249. fieldPosition, _ = field.Tag.Lookup("position")
  250. }
  251. typeTag, containsTypeTag := field.Tag.Lookup("type")
  252. if containsNameTag {
  253. if !containsTypeTag {
  254. // simple param
  255. key := prefix + name
  256. value := dataValue.Field(i).String()
  257. err = addParam(request, fieldPosition, key, value)
  258. if err != nil {
  259. return
  260. }
  261. } else if typeTag == "Repeated" {
  262. // repeated param
  263. repeatedFieldValue := dataValue.Field(i)
  264. if repeatedFieldValue.Kind() != reflect.Slice {
  265. // possible value: {"[]string", "*[]struct"}, we must call Elem() in the last condition
  266. repeatedFieldValue = repeatedFieldValue.Elem()
  267. }
  268. if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() {
  269. for m := 0; m < repeatedFieldValue.Len(); m++ {
  270. elementValue := repeatedFieldValue.Index(m)
  271. key := prefix + name + "." + strconv.Itoa(m+1)
  272. if elementValue.Type().Kind().String() == "string" {
  273. value := elementValue.String()
  274. err = addParam(request, fieldPosition, key, value)
  275. if err != nil {
  276. return
  277. }
  278. } else {
  279. err = flatRepeatedList(elementValue, request, fieldPosition, key+".")
  280. if err != nil {
  281. return
  282. }
  283. }
  284. }
  285. }
  286. }
  287. }
  288. }
  289. return
  290. }
  291. func addParam(request AcsRequest, position, name, value string) (err error) {
  292. if len(value) > 0 {
  293. switch position {
  294. case Header:
  295. request.addHeaderParam(name, value)
  296. case Query:
  297. request.addQueryParam(name, value)
  298. case Path:
  299. request.addPathParam(name, value)
  300. case Body:
  301. request.addFormParam(name, value)
  302. default:
  303. errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position)
  304. err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil)
  305. }
  306. }
  307. return
  308. }