acs_reqeust.go 6.6 KB

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