310 lines
7.1 KiB
Go
310 lines
7.1 KiB
Go
|
/*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package requests
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
|
||
|
"io"
|
||
|
"reflect"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
RPC = "RPC"
|
||
|
ROA = "ROA"
|
||
|
|
||
|
HTTP = "HTTP"
|
||
|
HTTPS = "HTTPS"
|
||
|
|
||
|
DefaultHttpPort = "80"
|
||
|
|
||
|
GET = "GET"
|
||
|
PUT = "PUT"
|
||
|
POST = "POST"
|
||
|
DELETE = "DELETE"
|
||
|
HEAD = "HEAD"
|
||
|
OPTIONS = "OPTIONS"
|
||
|
|
||
|
Json = "application/json"
|
||
|
Xml = "application/xml"
|
||
|
Raw = "application/octet-stream"
|
||
|
Form = "application/x-www-form-urlencoded"
|
||
|
|
||
|
Header = "Header"
|
||
|
Query = "Query"
|
||
|
Body = "Body"
|
||
|
Path = "Path"
|
||
|
|
||
|
HeaderSeparator = "\n"
|
||
|
)
|
||
|
|
||
|
// interface
|
||
|
type AcsRequest interface {
|
||
|
GetScheme() string
|
||
|
GetMethod() string
|
||
|
GetDomain() string
|
||
|
GetPort() string
|
||
|
GetRegionId() string
|
||
|
GetUrl() string
|
||
|
GetQueries() string
|
||
|
GetHeaders() map[string]string
|
||
|
GetQueryParams() map[string]string
|
||
|
GetFormParams() map[string]string
|
||
|
GetContent() []byte
|
||
|
GetBodyReader() io.Reader
|
||
|
GetStyle() string
|
||
|
GetProduct() string
|
||
|
GetVersion() string
|
||
|
GetActionName() string
|
||
|
GetAcceptFormat() string
|
||
|
GetLocationServiceCode() string
|
||
|
GetLocationEndpointType() string
|
||
|
|
||
|
SetStringToSign(stringToSign string)
|
||
|
GetStringToSign() string
|
||
|
|
||
|
SetDomain(domain string)
|
||
|
SetContent(content []byte)
|
||
|
SetScheme(scheme string)
|
||
|
BuildUrl() string
|
||
|
BuildQueries() string
|
||
|
|
||
|
addHeaderParam(key, value string)
|
||
|
addQueryParam(key, value string)
|
||
|
addFormParam(key, value string)
|
||
|
addPathParam(key, value string)
|
||
|
}
|
||
|
|
||
|
// base class
|
||
|
type baseRequest struct {
|
||
|
Scheme string
|
||
|
Method string
|
||
|
Domain string
|
||
|
Port string
|
||
|
RegionId string
|
||
|
|
||
|
product string
|
||
|
version string
|
||
|
|
||
|
actionName string
|
||
|
|
||
|
AcceptFormat string
|
||
|
|
||
|
QueryParams map[string]string
|
||
|
Headers map[string]string
|
||
|
FormParams map[string]string
|
||
|
Content []byte
|
||
|
|
||
|
locationServiceCode string
|
||
|
locationEndpointType string
|
||
|
|
||
|
queries string
|
||
|
|
||
|
stringToSign string
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetQueryParams() map[string]string {
|
||
|
return request.QueryParams
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetFormParams() map[string]string {
|
||
|
return request.FormParams
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetContent() []byte {
|
||
|
return request.Content
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetVersion() string {
|
||
|
return request.version
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetActionName() string {
|
||
|
return request.actionName
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) SetContent(content []byte) {
|
||
|
request.Content = content
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) addHeaderParam(key, value string) {
|
||
|
request.Headers[key] = value
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) addQueryParam(key, value string) {
|
||
|
request.QueryParams[key] = value
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) addFormParam(key, value string) {
|
||
|
request.FormParams[key] = value
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetAcceptFormat() string {
|
||
|
return request.AcceptFormat
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetLocationServiceCode() string {
|
||
|
return request.locationServiceCode
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetLocationEndpointType() string {
|
||
|
return request.locationEndpointType
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetProduct() string {
|
||
|
return request.product
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetScheme() string {
|
||
|
return request.Scheme
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) SetScheme(scheme string) {
|
||
|
request.Scheme = scheme
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetMethod() string {
|
||
|
return request.Method
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetDomain() string {
|
||
|
return request.Domain
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) SetDomain(host string) {
|
||
|
request.Domain = host
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetPort() string {
|
||
|
return request.Port
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetRegionId() string {
|
||
|
return request.RegionId
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetHeaders() map[string]string {
|
||
|
return request.Headers
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) SetContentType(contentType string) {
|
||
|
request.Headers["Content-Type"] = contentType
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetContentType() (contentType string, contains bool) {
|
||
|
contentType, contains = request.Headers["Content-Type"]
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) SetStringToSign(stringToSign string) {
|
||
|
request.stringToSign = stringToSign
|
||
|
}
|
||
|
|
||
|
func (request *baseRequest) GetStringToSign() string {
|
||
|
return request.stringToSign
|
||
|
}
|
||
|
|
||
|
func defaultBaseRequest() (request *baseRequest) {
|
||
|
request = &baseRequest{
|
||
|
Scheme: "",
|
||
|
AcceptFormat: "JSON",
|
||
|
Method: GET,
|
||
|
QueryParams: make(map[string]string),
|
||
|
Headers: map[string]string{
|
||
|
"x-sdk-client": "golang/1.0.0",
|
||
|
"x-sdk-invoke-type": "normal",
|
||
|
"Accept-Encoding": "identity",
|
||
|
},
|
||
|
FormParams: make(map[string]string),
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func InitParams(request AcsRequest) (err error) {
|
||
|
requestValue := reflect.ValueOf(request).Elem()
|
||
|
err = flatRepeatedList(requestValue, request, "", "")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, prefix string) (err error) {
|
||
|
dataType := dataValue.Type()
|
||
|
for i := 0; i < dataType.NumField(); i++ {
|
||
|
field := dataType.Field(i)
|
||
|
name, containsNameTag := field.Tag.Lookup("name")
|
||
|
fieldPosition := position
|
||
|
if fieldPosition == "" {
|
||
|
fieldPosition, _ = field.Tag.Lookup("position")
|
||
|
}
|
||
|
typeTag, containsTypeTag := field.Tag.Lookup("type")
|
||
|
if containsNameTag {
|
||
|
if !containsTypeTag {
|
||
|
// simple param
|
||
|
key := prefix + name
|
||
|
value := dataValue.Field(i).String()
|
||
|
err = addParam(request, fieldPosition, key, value)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
} else if typeTag == "Repeated" {
|
||
|
// repeated param
|
||
|
repeatedFieldValue := dataValue.Field(i)
|
||
|
if repeatedFieldValue.Kind() != reflect.Slice {
|
||
|
// possible value: {"[]string", "*[]struct"}, we must call Elem() in the last condition
|
||
|
repeatedFieldValue = repeatedFieldValue.Elem()
|
||
|
}
|
||
|
if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() {
|
||
|
for m := 0; m < repeatedFieldValue.Len(); m++ {
|
||
|
elementValue := repeatedFieldValue.Index(m)
|
||
|
key := prefix + name + "." + strconv.Itoa(m+1)
|
||
|
if elementValue.Type().String() == "string" {
|
||
|
value := elementValue.String()
|
||
|
err = addParam(request, fieldPosition, key, value)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
} else {
|
||
|
err = flatRepeatedList(elementValue, request, fieldPosition, key+".")
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func addParam(request AcsRequest, position, name, value string) (err error) {
|
||
|
if len(value) > 0 {
|
||
|
switch position {
|
||
|
case Header:
|
||
|
request.addHeaderParam(name, value)
|
||
|
case Query:
|
||
|
request.addQueryParam(name, value)
|
||
|
case Path:
|
||
|
request.addPathParam(name, value)
|
||
|
case Body:
|
||
|
request.addFormParam(name, value)
|
||
|
default:
|
||
|
errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position)
|
||
|
err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil)
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|