if field .Tag .Get ("marshal-as" ) == "blob" {
m = m .Convert (byteSliceType )
}
var err error
switch field .Tag .Get ("location" ) {
case "headers" :
err = buildHeaderMap (&r .HTTPRequest .Header , m , field .Tag )
case "header" :
err = buildHeader (&r .HTTPRequest .Header , m , name , field .Tag )
case "uri" :
err = buildURI (r .HTTPRequest .URL , m , name , field .Tag )
case "querystring" :
err = buildQueryString (query , m , name , field .Tag )
default :
if buildGETQuery {
err = buildQueryString (query , m , name , field .Tag )
}
}
r .Error = err
}
if r .Error != nil {
return
}
}
r .HTTPRequest .URL .RawQuery = query .Encode ()
if !aws .BoolValue (r .Config .DisableRestProtocolURICleaning ) {
cleanPath (r .HTTPRequest .URL )
}
}
func buildBody (r *request .Request , v reflect .Value ) {
if field , ok := v .Type ().FieldByName ("_" ); ok {
if payloadName := field .Tag .Get ("payload" ); payloadName != "" {
pfield , _ := v .Type ().FieldByName (payloadName )
if ptag := pfield .Tag .Get ("type" ); ptag != "" && ptag != "structure" {
payload := reflect .Indirect (v .FieldByName (payloadName ))
if payload .IsValid () && payload .Interface () != nil {
switch reader := payload .Interface ().(type ) {
case io .ReadSeeker :
r .SetReaderBody (reader )
case []byte :
r .SetBufferBody (reader )
case string :
r .SetStringBody (reader )
default :
r .Error = awserr .New (request .ErrCodeSerialization ,
"failed to encode REST request" ,
fmt .Errorf ("unknown payload type %s" , payload .Type ()))
}
}
}
}
}
}
func buildHeader (header *http .Header , v reflect .Value , name string , tag reflect .StructTag ) error {
str , err := convertType (v , tag )
if err == errValueNotSet {
return nil
} else if err != nil {
return awserr .New (request .ErrCodeSerialization , "failed to encode REST request" , err )
}
name = strings .TrimSpace (name )
str = strings .TrimSpace (str )
header .Add (name , str )
return nil
}
func buildHeaderMap (header *http .Header , v reflect .Value , tag reflect .StructTag ) error {
prefix := tag .Get ("locationName" )
for _ , key := range v .MapKeys () {
str , err := convertType (v .MapIndex (key ), tag )
if err == errValueNotSet {
continue
} else if err != nil {
return awserr .New (request .ErrCodeSerialization , "failed to encode REST request" , err )
}
keyStr := strings .TrimSpace (key .String ())
str = strings .TrimSpace (str )
header .Add (prefix +keyStr , str )
}
return nil
}
func buildURI (u *url .URL , v reflect .Value , name string , tag reflect .StructTag ) error {
value , err := convertType (v , tag )
if err == errValueNotSet {
return nil
} else if err != nil {
return awserr .New (request .ErrCodeSerialization , "failed to encode REST request" , err )
}
u .Path = strings .Replace (u .Path , "{" +name +"}" , value , -1 )
u .Path = strings .Replace (u .Path , "{" +name +"+}" , value , -1 )
u .RawPath = strings .Replace (u .RawPath , "{" +name +"}" , EscapePath (value , true ), -1 )
u .RawPath = strings .Replace (u .RawPath , "{" +name +"+}" , EscapePath (value , false ), -1 )
return nil
}
func buildQueryString (query url .Values , v reflect .Value , name string , tag reflect .StructTag ) error {
switch value := v .Interface ().(type ) {
case []*string :
for _ , item := range value {
query .Add (name , *item )
}
case map [string ]*string :
for key , item := range value {
query .Add (key , *item )
}
case map [string ][]*string :
for key , items := range value {
for _ , item := range items {
query .Add (key , *item )
}
}
default :
str , err := convertType (v , tag )
if err == errValueNotSet {
return nil
} else if err != nil {
return awserr .New (request .ErrCodeSerialization , "failed to encode REST request" , err )
}
query .Set (name , str )
}
return nil
}
func cleanPath (u *url .URL ) {
hasSlash := strings .HasSuffix (u .Path , "/" )