// Build builds the REST component of a service request. func Build(r *request.Request) { if r.ParamsFilled() { v := reflect.ValueOf(r.Params).Elem() buildLocationElements(r, v) buildBody(r, v) } }
// Build builds a JSON payload for a JSON RPC request. func Build(req *request.Request) { var buf []byte var err error if req.ParamsFilled() { buf, err = jsonutil.BuildJSON(req.Params) if err != nil { req.Error = awserr.New("SerializationError", "failed encoding JSON RPC request", err) return } } else { buf = emptyJSON } if req.Service.TargetPrefix != "" || string(buf) != "{}" { req.SetBufferBody(buf) } if req.Service.TargetPrefix != "" { target := req.Service.TargetPrefix + "." + req.Operation.Name req.HTTPRequest.Header.Add("X-Amz-Target", target) } if req.Service.JSONVersion != "" { jsonVersion := req.Service.JSONVersion req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion) } }
// UnmarshalError unmarshals an error response for a JSON RPC service. func UnmarshalError(req *request.Request) { defer req.HTTPResponse.Body.Close() bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) if err != nil { req.Error = awserr.New("SerializationError", "failed reading JSON RPC error response", err) return } if len(bodyBytes) == 0 { req.Error = awserr.NewRequestFailure( awserr.New("SerializationError", req.HTTPResponse.Status, nil), req.HTTPResponse.StatusCode, "", ) return } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { req.Error = awserr.New("SerializationError", "failed decoding JSON RPC error response", err) return } codes := strings.SplitN(jsonErr.Code, "#", 2) req.Error = awserr.NewRequestFailure( awserr.New(codes[len(codes)-1], jsonErr.Message, nil), req.HTTPResponse.StatusCode, req.RequestID, ) }
// UnmarshalMeta unmarshals the REST metadata of a response in a REST service func UnmarshalMeta(r *request.Request) { r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") if r.DataFilled() { v := reflect.Indirect(reflect.ValueOf(r.Data)) unmarshalLocationElements(r, v) } }
// Unmarshal unmarshals a response for a JSON RPC service. func Unmarshal(req *request.Request) { defer req.HTTPResponse.Body.Close() if req.DataFilled() { err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) if err != nil { req.Error = awserr.New("SerializationError", "failed decoding JSON RPC response", err) } } return }
// Sign requests with signature version 4. // // Will sign the requests with the service config's Credentials object // Signing is skipped if the credentials is the credentials.AnonymousCredentials // object. func Sign(req *request.Request) { // If the request does not need to be signed ignore the signing of the // request if the AnonymousCredentials object is used. if req.Service.Config.Credentials == credentials.AnonymousCredentials { return } region := req.Service.SigningRegion if region == "" { region = aws.StringValue(req.Service.Config.Region) } name := req.Service.SigningName if name == "" { name = req.Service.ServiceName } s := signer{ Request: req.HTTPRequest, Time: req.Time, ExpireTime: req.ExpireTime, Query: req.HTTPRequest.URL.Query(), Body: req.Body, ServiceName: name, Region: region, Credentials: req.Service.Config.Credentials, Debug: req.Service.Config.LogLevel.Value(), Logger: req.Service.Config.Logger, } req.Error = s.sign() }
func buildQueryString(r *request.Request, v reflect.Value, name string, query url.Values) { str, err := convertType(v) if err != nil { r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if str != nil { query.Set(name, *str) } }
func buildHeader(r *request.Request, v reflect.Value, name string) { str, err := convertType(v) if err != nil { r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if str != nil { r.HTTPRequest.Header.Add(name, *str) } }
func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() _, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) } // TODO extract the error... }
func unmarshalHandler(r *request.Request) { defer r.HTTPResponse.Body.Close() b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) } data := r.Data.(*metadataOutput) data.Content = string(b) }
func buildHeaderMap(r *request.Request, v reflect.Value, prefix string) { for _, key := range v.MapKeys() { str, err := convertType(v.MapIndex(key)) if err != nil { r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if str != nil { r.HTTPRequest.Header.Add(prefix+key.String(), *str) } } }
func buildURI(r *request.Request, v reflect.Value, name string) { value, err := convertType(v) if err != nil { r.Error = awserr.New("SerializationError", "failed to encode REST request", err) } else if value != nil { uri := r.HTTPRequest.URL.Path uri = strings.Replace(uri, "{"+name+"}", EscapePath(*value, true), -1) uri = strings.Replace(uri, "{"+name+"+}", EscapePath(*value, false), -1) r.HTTPRequest.URL.Path = uri } }
func unmarshalBody(r *request.Request, v reflect.Value) { if field, ok := v.Type().FieldByName("SDKShapeTraits"); ok { if payloadName := field.Tag.Get("payload"); payloadName != "" { pfield, _ := v.Type().FieldByName(payloadName) if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { payload := v.FieldByName(payloadName) if payload.IsValid() { switch payload.Interface().(type) { case []byte: b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) } else { payload.Set(reflect.ValueOf(b)) } case *string: b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) } else { str := string(b) payload.Set(reflect.ValueOf(&str)) } default: switch payload.Type().String() { case "io.ReadSeeker": payload.Set(reflect.ValueOf(aws.ReadSeekCloser(r.HTTPResponse.Body))) case "aws.ReadSeekCloser", "io.ReadCloser": payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) default: r.Error = awserr.New("SerializationError", "failed to decode REST response", fmt.Errorf("unknown payload type %s", payload.Type())) } } } } } } }
func unmarshalLocationElements(r *request.Request, v reflect.Value) { for i := 0; i < v.NumField(); i++ { m, field := v.Field(i), v.Type().Field(i) if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { continue } if m.IsValid() { name := field.Tag.Get("locationName") if name == "" { name = field.Name } switch field.Tag.Get("location") { case "statusCode": unmarshalStatusCode(m, r.HTTPResponse.StatusCode) case "header": err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name)) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) break } case "headers": prefix := field.Tag.Get("locationName") err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST response", err) break } } } if r.Error != nil { return } } }
func buildBody(r *request.Request, v reflect.Value) { if field, ok := v.Type().FieldByName("SDKShapeTraits"); 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("SerializationError", "failed to encode REST request", fmt.Errorf("unknown payload type %s", payload.Type())) } } } } } }
// ShouldRetry returns if the request should be retried. func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { if r.HTTPResponse.StatusCode >= 500 { return true } return r.IsErrorRetryable() }
// Unmarshal unmarshals the REST component of a response in a REST service. func Unmarshal(r *request.Request) { if r.DataFilled() { v := reflect.Indirect(reflect.ValueOf(r.Data)) unmarshalBody(r, v) } }
func validateEndpointHandler(r *request.Request) { if r.Service.Endpoint == "" { r.Error = aws.ErrMissingEndpoint } }