func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() if r.HTTPResponse.StatusCode == http.StatusMovedPermanently { r.Error = awserr.New("BucketRegionError", fmt.Sprintf("incorrect region, the bucket is not in '%s' region", aws.StringValue(r.Service.Config.Region)), nil) return } if r.HTTPResponse.ContentLength == int64(0) { // No body, use status code to generate an awserr.Error r.Error = awserr.NewRequestFailure( awserr.New(strings.Replace(r.HTTPResponse.Status, " ", "", -1), r.HTTPResponse.Status, nil), r.HTTPResponse.StatusCode, "", ) return } resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { r.Error = awserr.New("SerializationError", "failed to decode S3 XML error response", nil) } else { r.Error = awserr.NewRequestFailure( awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, "", ) } }
// UnmarshalError unmarshals a response error for the REST JSON protocol. func UnmarshalError(r *request.Request) { code := r.HTTPResponse.Header.Get("X-Amzn-Errortype") bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed reading REST JSON error response", err) return } if len(bodyBytes) == 0 { r.Error = awserr.NewRequestFailure( awserr.New("SerializationError", r.HTTPResponse.Status, nil), r.HTTPResponse.StatusCode, "", ) return } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { r.Error = awserr.New("SerializationError", "failed decoding REST JSON error response", err) return } if code == "" { code = jsonErr.Code } code = strings.SplitN(code, ":", 2)[0] r.Error = awserr.NewRequestFailure( awserr.New(code, jsonErr.Message, nil), r.HTTPResponse.StatusCode, r.RequestID, ) }
func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() if r.HTTPResponse.ContentLength == int64(0) { // No body, use status code to generate an awserr.Error r.Error = awserr.NewRequestFailure( awserr.New(strings.Replace(r.HTTPResponse.Status, " ", "", -1), r.HTTPResponse.Status, nil), r.HTTPResponse.StatusCode, "", ) return } resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { r.Error = awserr.New("SerializationError", "failed to decode SimpleDB XML error response", nil) } else if len(resp.Errors) == 0 { r.Error = awserr.New("MissingError", "missing error code in SimpleDB XML error response", nil) } else { // If there are multiple error codes, return only the first as the aws.Error interface only supports // one error code. r.Error = awserr.NewRequestFailure( awserr.New(resp.Errors[0].Code, resp.Errors[0].Message, nil), r.HTTPResponse.StatusCode, resp.RequestID, ) } }
// 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, ) }
// presignURL will presign the request by using SoureRegion to sign with. SourceRegion is not // sent to the service, and is only used to not have the SDKs parsing ARNs. func presignURL(r *request.Request, sourceRegion *string, newParams interface{}) *string { cfg := r.Config.Copy(aws.NewConfig(). WithEndpoint(""). WithRegion(aws.StringValue(sourceRegion))) clientInfo := r.ClientInfo resolved, err := r.Config.EndpointResolver.EndpointFor( clientInfo.ServiceName, aws.StringValue(cfg.Region), func(opt *endpoints.Options) { opt.DisableSSL = aws.BoolValue(cfg.DisableSSL) opt.UseDualStack = aws.BoolValue(cfg.UseDualStack) }, ) if err != nil { r.Error = err return nil } clientInfo.Endpoint = resolved.URL clientInfo.SigningRegion = resolved.SigningRegion // Presign a request with modified params req := request.New(*cfg, clientInfo, r.Handlers, r.Retryer, r.Operation, newParams, r.Data) req.Operation.HTTPMethod = "GET" uri, err := req.Presign(5 * time.Minute) // 5 minutes should be enough. if err != nil { // bubble error back up to original request r.Error = err return nil } // We have our URL, set it on params return &uri }
func unmarshalError(req *request.Request) { bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body) if err != nil { req.Error = awserr.New("UnmarshaleError", req.HTTPResponse.Status, err) return } if len(bodyBytes) == 0 { req.Error = awserr.NewRequestFailure( awserr.New("UnmarshaleError", req.HTTPResponse.Status, fmt.Errorf("empty body")), req.HTTPResponse.StatusCode, "", ) return } var jsonErr jsonErrorResponse if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil { req.Error = awserr.New("UnmarshaleError", "JSON unmarshal", err) return } req.Error = awserr.NewRequestFailure( awserr.New(jsonErr.Code, jsonErr.Message, nil), req.HTTPResponse.StatusCode, "", ) }
func unmarshalChangeResourceRecordSetsError(r *request.Request) { defer r.HTTPResponse.Body.Close() responseBody, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to read Route53 XML error response", err) return } baseError := &baseXMLErrorResponse{} if err := xml.Unmarshal(responseBody, baseError); err != nil { r.Error = awserr.New("SerializationError", "failed to decode Route53 XML error response", err) return } switch baseError.XMLName.Local { case "InvalidChangeBatch": unmarshalInvalidChangeBatchError(r, responseBody) default: r.HTTPResponse.Body = ioutil.NopCloser(bytes.NewReader(responseBody)) restxml.UnmarshalError(r) } }
func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() b := &bytes.Buffer{} if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) return } // Response body format is not consistent between metadata endpoints. // Grab the error message as a string and include that as the source error r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())) }
func unmarshalBody(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 := v.FieldByName(payloadName) if payload.IsValid() { switch payload.Interface().(type) { case []byte: defer r.HTTPResponse.Body.Close() 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: defer r.HTTPResponse.Body.Close() 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.ReadCloser": payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) case "io.ReadSeeker": b, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to read response body", err) return } payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b)))) default: io.Copy(ioutil.Discard, r.HTTPResponse.Body) defer r.HTTPResponse.Body.Close() r.Error = awserr.New("SerializationError", "failed to decode REST response", fmt.Errorf("unknown payload type %s", payload.Type())) } } } } } } }
func unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() var errOut errorOutput if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil { r.Error = awserr.New("SerializationError", "failed to decode endpoint credentials", err, ) } // Response body format is not consistent between metadata endpoints. // Grab the error message as a string and include that as the source error r.Error = awserr.New(errOut.Code, errOut.Message, nil) }
// UnmarshalError unmarshals a response error for the EC2 protocol. func UnmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { r.Error = awserr.New("SerializationError", "failed decoding EC2 Query error response", err) } else { r.Error = awserr.NewRequestFailure( awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, resp.RequestID, ) } }
func fillPresignedURL(r *request.Request) { if !r.ParamsFilled() { return } origParams := r.Params.(*CopySnapshotInput) // Stop if PresignedURL/DestinationRegion is set if origParams.PresignedUrl != nil || origParams.DestinationRegion != nil { return } origParams.DestinationRegion = r.Config.Region newParams := awsutil.CopyOf(r.Params).(*CopySnapshotInput) // Create a new request based on the existing request. We will use this to // presign the CopySnapshot request against the source region. cfg := r.Config.Copy(aws.NewConfig(). WithEndpoint(""). WithRegion(aws.StringValue(origParams.SourceRegion))) clientInfo := r.ClientInfo resolved, err := r.Config.EndpointResolver.EndpointFor( clientInfo.ServiceName, aws.StringValue(cfg.Region), func(opt *endpoints.Options) { opt.DisableSSL = aws.BoolValue(cfg.DisableSSL) opt.UseDualStack = aws.BoolValue(cfg.UseDualStack) }, ) if err != nil { r.Error = err return } clientInfo.Endpoint = resolved.URL clientInfo.SigningRegion = resolved.SigningRegion // Presign a CopySnapshot request with modified params req := request.New(*cfg, clientInfo, r.Handlers, r.Retryer, r.Operation, newParams, r.Data) url, err := req.Presign(5 * time.Minute) // 5 minutes should be enough. if err != nil { // bubble error back up to original request r.Error = err return } // We have our URL, set it on params origParams.PresignedUrl = &url }
// 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.ClientInfo.TargetPrefix != "" || string(buf) != "{}" { req.SetBufferBody(buf) } if req.ClientInfo.TargetPrefix != "" { target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name req.HTTPRequest.Header.Add("X-Amz-Target", target) } if req.ClientInfo.JSONVersion != "" { jsonVersion := req.ClientInfo.JSONVersion req.HTTPRequest.Header.Add("Content-Type", "application/x-amz-json-"+jsonVersion) } }
// 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.Config.Credentials == credentials.AnonymousCredentials { return } region := req.ClientInfo.SigningRegion if region == "" { region = aws.StringValue(req.Config.Region) } name := req.ClientInfo.SigningName if name == "" { name = req.ClientInfo.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.Config.Credentials, Debug: req.Config.LogLevel.Value(), Logger: req.Config.Logger, } req.Error = s.sign() }
// SignSDKRequest signs an AWS request with the V4 signature. This // request handler is bested used only with the SDK's built in service client's // API operation requests. // // This function should not be used on its on its own, but in conjunction with // an AWS service client's API operation call. To sign a standalone request // not created by a service client's API operation method use the "Sign" or // "Presign" functions of the "Signer" type. // // If the credentials of the request's config are set to // credentials.AnonymousCredentials the request will not be signed. func SignSDKRequest(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.Config.Credentials == credentials.AnonymousCredentials { return } region := req.ClientInfo.SigningRegion if region == "" { region = aws.StringValue(req.Config.Region) } name := req.ClientInfo.SigningName if name == "" { name = req.ClientInfo.ServiceName } v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) { v4.Debug = req.Config.LogLevel.Value() v4.Logger = req.Config.Logger v4.DisableHeaderHoisting = req.NotHoist }) signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.Body, name, region, req.ExpireTime, req.Time) req.SignedHeaderVals = signedHeaders req.Error = err }
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 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 validateSSERequiresSSL(r *request.Request) { if r.HTTPRequest.URL.Scheme != "https" { p := awsutil.ValuesAtPath(r.Params, "SSECustomerKey||CopySourceSSECustomerKey") if len(p) > 0 { r.Error = errSSERequiresSSL } } }
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 buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) { query := r.HTTPRequest.URL.Query() // Setup the raw path to match the base path pattern. This is needed // so that when the path is mutated a custom escaped version can be // stored in RawPath that will be used by the Go client. r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path for i := 0; i < v.NumField(); i++ { m := v.Field(i) if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) { continue } if m.IsValid() { field := v.Type().Field(i) name := field.Tag.Get("locationName") if name == "" { name = field.Name } if m.Kind() == reflect.Ptr { m = m.Elem() } if !m.IsValid() { continue } if field.Tag.Get("ignore") != "" { continue } var err error switch field.Tag.Get("location") { case "headers": // header maps err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag.Get("locationName")) case "header": err = buildHeader(&r.HTTPRequest.Header, m, name) case "uri": err = buildURI(r.HTTPRequest.URL, m, name) case "querystring": err = buildQueryString(query, m, name) default: if buildGETQuery { err = buildQueryString(query, m, name) } } 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 unmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() defer io.Copy(ioutil.Discard, r.HTTPResponse.Body) // Bucket exists in a different region, and request needs // to be made to the correct region. if r.HTTPResponse.StatusCode == http.StatusMovedPermanently { r.Error = awserr.NewRequestFailure( awserr.New("BucketRegionError", fmt.Sprintf("incorrect region, the bucket is not in '%s' region", aws.StringValue(r.Config.Region)), nil), r.HTTPResponse.StatusCode, r.RequestID, ) return } var errCode, errMsg string // Attempt to parse error from body if it is known resp := &xmlErrorResponse{} err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) if err != nil && err != io.EOF { errCode = "SerializationError" errMsg = "failed to decode S3 XML error response" } else { errCode = resp.Code errMsg = resp.Message } // Fallback to status code converted to message if still no error code if len(errCode) == 0 { statusText := http.StatusText(r.HTTPResponse.StatusCode) errCode = strings.Replace(statusText, " ", "", -1) errMsg = statusText } r.Error = awserr.NewRequestFailure( awserr.New(errCode, errMsg, nil), r.HTTPResponse.StatusCode, r.RequestID, ) }
// 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 }
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 } }
// Unmarshal unmarshals a response body for the EC2 protocol. func Unmarshal(r *request.Request) { defer r.HTTPResponse.Body.Close() if r.DataFilled() { decoder := xml.NewDecoder(r.HTTPResponse.Body) err := xmlutil.UnmarshalXML(r.Data, decoder, "") if err != nil { r.Error = awserr.New("SerializationError", "failed decoding EC2 Query response", err) return } } }
func unmarshalHandler(r *request.Request) { defer r.HTTPResponse.Body.Close() out := r.Data.(*getCredentialsOutput) if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil { r.Error = awserr.New("SerializationError", "failed to decode endpoint credentials", err, ) } }
// Unmarshal unmarshals a payload response for the REST XML protocol. func Unmarshal(r *request.Request) { if t := rest.PayloadType(r.Data); t == "structure" || t == "" { defer r.HTTPResponse.Body.Close() decoder := xml.NewDecoder(r.HTTPResponse.Body) err := xmlutil.UnmarshalXML(r.Data, decoder, "") if err != nil { r.Error = awserr.New("SerializationError", "failed to decode REST XML response", err) return } } }
// UnmarshalError unmarshals an error response for an AWS Query service. func UnmarshalError(r *request.Request) { defer r.HTTPResponse.Body.Close() bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) if err != nil { r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err) return } // First check for specific error resp := xmlErrorResponse{} decodeErr := xml.Unmarshal(bodyBytes, &resp) if decodeErr == nil { reqID := resp.RequestID if reqID == "" { reqID = r.RequestID } r.Error = awserr.NewRequestFailure( awserr.New(resp.Code, resp.Message, nil), r.HTTPResponse.StatusCode, reqID, ) return } // Check for unhandled error servUnavailResp := xmlServiceUnavailableResponse{} unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp) if unavailErr == nil { r.Error = awserr.NewRequestFailure( awserr.New("ServiceUnavailableException", "service is unavailable", nil), r.HTTPResponse.StatusCode, r.RequestID, ) return } // Failed to retrieve any error message from the response body r.Error = awserr.New("SerializationError", "failed to decode query XML error response", decodeErr) }
func unmarshalHandler(r *request.Request) { defer r.HTTPResponse.Body.Close() b := &bytes.Buffer{} if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) return } if data, ok := r.Data.(*metadataOutput); ok { data.Content = b.String() } }