acs_reqeust.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
  18. "io"
  19. "reflect"
  20. "strconv"
  21. )
  22. const (
  23. RPC = "RPC"
  24. ROA = "ROA"
  25. HTTP = "HTTP"
  26. HTTPS = "HTTPS"
  27. DefaultHttpPort = "80"
  28. GET = "GET"
  29. PUT = "PUT"
  30. POST = "POST"
  31. DELETE = "DELETE"
  32. HEAD = "HEAD"
  33. OPTIONS = "OPTIONS"
  34. Json = "application/json"
  35. Xml = "application/xml"
  36. Raw = "application/octet-stream"
  37. Form = "application/x-www-form-urlencoded"
  38. Header = "Header"
  39. Query = "Query"
  40. Body = "Body"
  41. Path = "Path"
  42. HeaderSeparator = "\n"
  43. )
  44. // interface
  45. type AcsRequest interface {
  46. GetScheme() string
  47. GetMethod() string
  48. GetDomain() string
  49. GetPort() string
  50. GetRegionId() string
  51. GetUrl() string
  52. GetQueries() 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. SetStringToSign(stringToSign string)
  66. GetStringToSign() string
  67. SetDomain(domain string)
  68. SetContent(content []byte)
  69. BuildUrl() string
  70. BuildQueries() string
  71. addHeaderParam(key, value string)
  72. addQueryParam(key, value string)
  73. addFormParam(key, value string)
  74. addPathParam(key, value string)
  75. }
  76. // base class
  77. type baseRequest struct {
  78. Scheme string
  79. Method string
  80. Domain string
  81. Port string
  82. RegionId string
  83. product string
  84. version string
  85. actionName string
  86. AcceptFormat string
  87. QueryParams map[string]string
  88. Headers map[string]string
  89. FormParams map[string]string
  90. Content []byte
  91. locationServiceCode string
  92. locationEndpointType string
  93. queries string
  94. stringToSign string
  95. }
  96. func (request *baseRequest) GetQueryParams() map[string]string {
  97. return request.QueryParams
  98. }
  99. func (request *baseRequest) GetFormParams() map[string]string {
  100. return request.FormParams
  101. }
  102. func (request *baseRequest) GetContent() []byte {
  103. return request.Content
  104. }
  105. func (request *baseRequest) GetVersion() string {
  106. return request.version
  107. }
  108. func (request *baseRequest) GetActionName() string {
  109. return request.actionName
  110. }
  111. func (request *baseRequest) SetContent(content []byte) {
  112. request.Content = content
  113. }
  114. func (request *baseRequest) addHeaderParam(key, value string) {
  115. request.Headers[key] = value
  116. }
  117. func (request *baseRequest) addQueryParam(key, value string) {
  118. request.QueryParams[key] = value
  119. }
  120. func (request *baseRequest) addFormParam(key, value string) {
  121. request.FormParams[key] = value
  122. }
  123. func (request *baseRequest) GetAcceptFormat() string {
  124. return request.AcceptFormat
  125. }
  126. func (request *baseRequest) GetLocationServiceCode() string {
  127. return request.locationServiceCode
  128. }
  129. func (request *baseRequest) GetLocationEndpointType() string {
  130. return request.locationEndpointType
  131. }
  132. func (request *baseRequest) GetProduct() string {
  133. return request.product
  134. }
  135. func (request *baseRequest) GetScheme() string {
  136. return request.Scheme
  137. }
  138. func (request *baseRequest) GetMethod() string {
  139. return request.Method
  140. }
  141. func (request *baseRequest) GetDomain() string {
  142. return request.Domain
  143. }
  144. func (request *baseRequest) SetDomain(host string) {
  145. request.Domain = host
  146. }
  147. func (request *baseRequest) GetPort() string {
  148. return request.Port
  149. }
  150. func (request *baseRequest) GetRegionId() string {
  151. return request.RegionId
  152. }
  153. func (request *baseRequest) GetHeaders() map[string]string {
  154. return request.Headers
  155. }
  156. func (request *baseRequest) SetContentType(contentType string) {
  157. request.Headers["Content-Type"] = contentType
  158. }
  159. func (request *baseRequest) GetContentType() (contentType string, contains bool) {
  160. contentType, contains = request.Headers["Content-Type"]
  161. return
  162. }
  163. func (request *baseRequest) SetStringToSign(stringToSign string) {
  164. request.stringToSign = stringToSign
  165. }
  166. func (request *baseRequest) GetStringToSign() string {
  167. return request.stringToSign
  168. }
  169. func defaultBaseRequest() (request *baseRequest) {
  170. request = &baseRequest{
  171. Scheme: HTTP,
  172. AcceptFormat: "JSON",
  173. Method: GET,
  174. QueryParams: make(map[string]string),
  175. Headers: map[string]string{
  176. "x-sdk-client": "golang/1.0.0",
  177. "x-sdk-invoke-type": "normal",
  178. },
  179. FormParams: make(map[string]string),
  180. }
  181. return
  182. }
  183. func InitParams(request AcsRequest) (err error) {
  184. requestValue := reflect.ValueOf(request).Elem()
  185. err = flatRepeatedList(requestValue, request, "", "")
  186. return
  187. }
  188. func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, prefix string) (err error) {
  189. dataType := dataValue.Type()
  190. for i := 0; i < dataType.NumField(); i++ {
  191. field := dataType.Field(i)
  192. name, containsNameTag := field.Tag.Lookup("name")
  193. fieldPosition := position
  194. if fieldPosition == "" {
  195. fieldPosition, _ = field.Tag.Lookup("position")
  196. }
  197. typeTag, containsTypeTag := field.Tag.Lookup("type")
  198. if containsNameTag {
  199. if !containsTypeTag {
  200. // simple param
  201. key := prefix + name
  202. value := dataValue.Field(i).String()
  203. err = addParam(request, fieldPosition, key, value)
  204. if err != nil {
  205. return
  206. }
  207. } else if typeTag == "Repeated" {
  208. // repeated param
  209. repeatedFieldValue := dataValue.Field(i)
  210. if repeatedFieldValue.Kind() != reflect.Slice {
  211. // possible value: {"[]string", "*[]struct"}, we must call Elem() in the last condition
  212. repeatedFieldValue = repeatedFieldValue.Elem()
  213. }
  214. if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() {
  215. for m := 0; m < repeatedFieldValue.Len(); m++ {
  216. elementValue := repeatedFieldValue.Index(m)
  217. key := prefix + name + "." + strconv.Itoa(m+1)
  218. if elementValue.Type().String() == "string" {
  219. value := elementValue.String()
  220. err = addParam(request, fieldPosition, key, value)
  221. if err != nil {
  222. return
  223. }
  224. } else {
  225. err = flatRepeatedList(elementValue, request, fieldPosition, key+".")
  226. if err != nil {
  227. return
  228. }
  229. }
  230. }
  231. }
  232. }
  233. }
  234. }
  235. return
  236. }
  237. func addParam(request AcsRequest, position, name, value string) (err error) {
  238. if len(value) > 0 {
  239. switch position {
  240. case Header:
  241. request.addHeaderParam(name, value)
  242. case Query:
  243. request.addQueryParam(name, value)
  244. case Path:
  245. request.addPathParam(name, value)
  246. case Body:
  247. request.addFormParam(name, value)
  248. default:
  249. errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position)
  250. err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil)
  251. }
  252. }
  253. return
  254. }