response.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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 responses
  15. import (
  16. "bytes"
  17. "encoding/xml"
  18. "fmt"
  19. "io/ioutil"
  20. "net/http"
  21. "strings"
  22. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
  23. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils"
  24. )
  25. type AcsResponse interface {
  26. IsSuccess() bool
  27. GetHttpStatus() int
  28. GetHttpHeaders() map[string][]string
  29. GetHttpContentString() string
  30. GetHttpContentBytes() []byte
  31. GetOriginHttpResponse() *http.Response
  32. parseFromHttpResponse(httpResponse *http.Response) error
  33. }
  34. var debug utils.Debug
  35. func init() {
  36. debug = utils.Init("sdk")
  37. }
  38. // Unmarshal object from http response body to target Response
  39. func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) {
  40. err = response.parseFromHttpResponse(httpResponse)
  41. if err != nil {
  42. return
  43. }
  44. if !response.IsSuccess() {
  45. err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), "")
  46. return
  47. }
  48. if _, isCommonResponse := response.(*CommonResponse); isCommonResponse {
  49. // common response need not unmarshal
  50. return
  51. }
  52. if len(response.GetHttpContentBytes()) == 0 {
  53. return
  54. }
  55. if strings.ToUpper(format) == "JSON" {
  56. initJsonParserOnce()
  57. err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response)
  58. if err != nil {
  59. err = errors.NewClientError(errors.JsonUnmarshalErrorCode, errors.JsonUnmarshalErrorMessage, err)
  60. }
  61. } else if strings.ToUpper(format) == "XML" {
  62. err = xml.Unmarshal(response.GetHttpContentBytes(), response)
  63. }
  64. return
  65. }
  66. type BaseResponse struct {
  67. httpStatus int
  68. httpHeaders map[string][]string
  69. httpContentString string
  70. httpContentBytes []byte
  71. originHttpResponse *http.Response
  72. }
  73. func (baseResponse *BaseResponse) GetHttpStatus() int {
  74. return baseResponse.httpStatus
  75. }
  76. func (baseResponse *BaseResponse) GetHttpHeaders() map[string][]string {
  77. return baseResponse.httpHeaders
  78. }
  79. func (baseResponse *BaseResponse) GetHttpContentString() string {
  80. return baseResponse.httpContentString
  81. }
  82. func (baseResponse *BaseResponse) GetHttpContentBytes() []byte {
  83. return baseResponse.httpContentBytes
  84. }
  85. func (baseResponse *BaseResponse) GetOriginHttpResponse() *http.Response {
  86. return baseResponse.originHttpResponse
  87. }
  88. func (baseResponse *BaseResponse) IsSuccess() bool {
  89. if baseResponse.GetHttpStatus() >= 200 && baseResponse.GetHttpStatus() < 300 {
  90. return true
  91. }
  92. return false
  93. }
  94. func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Response) (err error) {
  95. defer httpResponse.Body.Close()
  96. body, err := ioutil.ReadAll(httpResponse.Body)
  97. if err != nil {
  98. return
  99. }
  100. debug("< %s", string(body))
  101. baseResponse.httpStatus = httpResponse.StatusCode
  102. baseResponse.httpHeaders = httpResponse.Header
  103. baseResponse.httpContentBytes = body
  104. baseResponse.httpContentString = string(body)
  105. baseResponse.originHttpResponse = httpResponse
  106. return
  107. }
  108. func (baseResponse *BaseResponse) String() string {
  109. resultBuilder := bytes.Buffer{}
  110. // statusCode
  111. // resultBuilder.WriteString("\n")
  112. resultBuilder.WriteString(fmt.Sprintf("%s %s\n", baseResponse.originHttpResponse.Proto, baseResponse.originHttpResponse.Status))
  113. // httpHeaders
  114. //resultBuilder.WriteString("Headers:\n")
  115. for key, value := range baseResponse.httpHeaders {
  116. resultBuilder.WriteString(key + ": " + strings.Join(value, ";") + "\n")
  117. }
  118. resultBuilder.WriteString("\n")
  119. // content
  120. //resultBuilder.WriteString("Content:\n")
  121. resultBuilder.WriteString(baseResponse.httpContentString + "\n")
  122. return resultBuilder.String()
  123. }
  124. type CommonResponse struct {
  125. *BaseResponse
  126. }
  127. func NewCommonResponse() (response *CommonResponse) {
  128. return &CommonResponse{
  129. BaseResponse: &BaseResponse{},
  130. }
  131. }