Add requset post support (#70)

* add requset post support

* fix travis

* fix go lint
This commit is contained in:
runzexia 2017-12-07 14:12:16 +08:00 committed by Xuanwo
parent 547691370d
commit ed8aa5d7ac
2 changed files with 59 additions and 21 deletions

View File

@ -34,6 +34,7 @@ import (
// Builder is the request builder for QingCloud service.
type Builder struct {
parsedURL string
parsedForm url.Values
parsedProperties *map[string]string
parsedParams *map[string]string
@ -56,14 +57,15 @@ func (b *Builder) BuildHTTPRequest(o *data.Operation, i *reflect.Value) (*http.R
func (b *Builder) build() (*http.Request, error) {
httpRequest, err := http.NewRequest(b.operation.RequestMethod, b.parsedURL, nil)
httpRequest.Form = b.parsedForm
if err != nil {
return nil, err
}
logger.Info(fmt.Sprintf(
"Built QingCloud request: [%d] %s",
"Built QingCloud request: [%d] %s \n %s ",
utils.StringToUnixInt(httpRequest.Header.Get("Date"), "RFC 822"),
httpRequest.URL.String()))
httpRequest.URL.String(), b.parsedForm))
return httpRequest, nil
}
@ -82,6 +84,10 @@ func (b *Builder) parse() error {
if err != nil {
return err
}
err = b.parseRequestForm()
if err != nil {
return err
}
return nil
}
@ -218,7 +224,7 @@ func (b *Builder) parseRequestURL() error {
b.parsedURL = endpoint + requestURI
if b.parsedParams != nil {
if b.parsedParams != nil && b.operation.RequestMethod == "GET" {
zone := (*b.parsedProperties)["zone"]
if zone != "" {
(*b.parsedParams)["zone"] = zone
@ -236,3 +242,18 @@ func (b *Builder) parseRequestURL() error {
return nil
}
func (b *Builder) parseRequestForm() error {
if b.parsedParams != nil && b.operation.RequestMethod == "POST" {
var values = make(url.Values)
zone := (*b.parsedProperties)["zone"]
if zone != "" {
(*b.parsedParams)["zone"] = zone
}
for key, value := range *b.parsedParams {
values.Set(key, url.QueryEscape(value))
}
b.parsedForm = values
}
return nil
}

View File

@ -36,7 +36,8 @@ type Signer struct {
AccessKeyID string
SecretAccessKey string
BuiltURL string
BuiltURL string
BuiltForm string
}
// WriteSignature calculates signature and write it to http request.
@ -47,11 +48,12 @@ func (is *Signer) WriteSignature(request *http.Request) error {
}
newRequest, err := http.NewRequest(request.Method,
request.URL.Scheme+"://"+request.URL.Host+is.BuiltURL, nil)
request.URL.Scheme+"://"+request.URL.Host+is.BuiltURL, strings.NewReader(is.BuiltForm))
if err != nil {
return err
}
request.URL = newRequest.URL
request.Body = newRequest.Body
logger.Info(fmt.Sprintf(
"Signed QingCloud request: [%d] %s",
@ -79,34 +81,44 @@ func (is *Signer) BuildSignature(request *http.Request) (string, error) {
"QingCloud signature: [%d] %s",
utils.StringToUnixInt(request.Header.Get("Date"), "RFC 822"),
signature))
is.BuiltURL += "&signature=" + signature
if request.Method == "GET" {
is.BuiltURL += "&signature=" + signature
} else if request.Method == "POST" {
is.BuiltForm += "&signature=" + signature
}
return signature, nil
}
// BuildStringToSign build the string to sign.
func (is *Signer) BuildStringToSign(request *http.Request) (string, error) {
query := request.URL.Query()
query.Set("access_key_id", is.AccessKeyID)
query.Set("signature_method", "HmacSHA256")
query.Set("signature_version", "1")
if request.Method == "GET" {
return is.BuildStringToSignByValues(request.Header.Get("Date"), request.Method, request.URL.Path, request.URL.Query())
} else if request.Method == "POST" {
return is.BuildStringToSignByValues(request.Header.Get("Date"), request.Method, request.URL.Path, request.Form)
}
return "", fmt.Errorf("Requset Type Not Support For Sign ")
}
// BuildStringToSignByValues build the string to sign.
func (is *Signer) BuildStringToSignByValues(requestDate string, requestMethod string, requestPath string, requestParams url.Values) (string, error) {
requestParams.Set("access_key_id", is.AccessKeyID)
requestParams.Set("signature_method", "HmacSHA256")
requestParams.Set("signature_version", "1")
var timeValue time.Time
if request.Header.Get("Date") != "" {
if requestDate != "" {
var err error
timeValue, err = utils.StringToTime(request.Header.Get("Date"), "RFC 822")
timeValue, err = utils.StringToTime(requestDate, "RFC 822")
if err != nil {
return "", err
}
} else {
timeValue = time.Now()
}
query.Set("time_stamp", utils.TimeToString(timeValue, "ISO 8601"))
requestParams.Set("time_stamp", utils.TimeToString(timeValue, "ISO 8601"))
keys := []string{}
for key := range query {
for key := range requestParams {
keys = append(keys, key)
}
@ -114,7 +126,7 @@ func (is *Signer) BuildStringToSign(request *http.Request) (string, error) {
parts := []string{}
for _, key := range keys {
values := query[key]
values := requestParams[key]
if len(values) > 0 {
if values[0] != "" {
value := strings.TrimSpace(strings.Join(values, ""))
@ -131,14 +143,19 @@ func (is *Signer) BuildStringToSign(request *http.Request) (string, error) {
urlParams := strings.Join(parts, "&")
stringToSign := request.Method + "\n" + request.URL.Path + "\n" + urlParams
stringToSign := requestMethod + "\n" + requestPath + "\n" + urlParams
logger.Debug(fmt.Sprintf(
"QingCloud string to sign: [%d] %s",
utils.StringToUnixInt(request.Header.Get("Date"), "RFC 822"),
"QingCloud string to sign: %s",
stringToSign))
is.BuiltURL = request.URL.Path + "?" + urlParams
if requestMethod == "GET" {
is.BuiltURL = requestPath + "?" + urlParams
is.BuiltForm = ""
} else if requestMethod == "POST" {
is.BuiltURL = requestPath
is.BuiltForm = urlParams
}
return stringToSign, nil
}