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