acs_request.go 7.1 KB

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