acs_request.go 7.1 KB

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