acs_reqeust.go 6.7 KB

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