acs_reqeust.go 6.0 KB

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