// 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 }
// GetMetadata uses the path provided to request func (c *Client) GetMetadata(p string) (string, error) { op := &request.Operation{ Name: "GetMetadata", HTTPMethod: "GET", HTTPPath: path.Join("/", "meta-data", p), } output := &metadataOutput{} req := request.New(c.Service.ServiceInfo, c.Service.Handlers, c.Service.Retryer, op, nil, output) return output.Content, req.Send() }
// go version 1.4 and 1.5 do not return an error. Version 1.5 will url encode // the uri while 1.4 will not func TestRequestInvalidEndpoint(t *testing.T) { endpoint, _ := endpoints.NormalizeEndpoint("localhost:80 ", "test-service", "test-region", false) r := request.New( aws.Config{}, metadata.ClientInfo{Endpoint: endpoint}, defaults.Handlers(), client.DefaultRetryer{}, &request.Operation{}, nil, nil, ) assert.Error(t, r.Error) }
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 }
func (self *MockS3) PutObjectRequest(input *s3.PutObjectInput) (*request.Request, *s3.PutObjectOutput) { self.Lock() defer self.Unlock() // required for s3manager.Upload // TODO: should only alter bucket on Send() content, _ := ioutil.ReadAll(input.Body) req := request.New(aws.Config{}, metadata.ClientInfo{}, request.Handlers{}, nil, &request.Operation{}, nil, nil) if bucket, ok := self.data[*input.Bucket]; ok { bucket[*input.Key] = content } else { // pre-set the error on the request req.Build() req.Error = ErrNoSuchBucket } return req, &s3.PutObjectOutput{} }
// NewRequest returns a new Request pointer for the service API // operation and parameters. func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request { return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data) }
func NewSigningProxy(target *url.URL, creds *credentials.Credentials, region string) *httputil.ReverseProxy { director := func(req *http.Request) { // Rewrite request to desired server host req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.Host = target.Host // To perform the signing, we leverage aws-sdk-go // aws.request performs more functions than we need here // we only populate enough of the fields to successfully // sign the request config := aws.NewConfig().WithCredentials(creds) if len(strings.TrimSpace(region)) > 0 { config = config.WithRegion(region) } else { config = config.WithRegion("us-west-2") } clientInfo := metadata.ClientInfo{ ServiceName: "es", } operation := &request.Operation{ Name: "", HTTPMethod: req.Method, HTTPPath: req.URL.Path, } handlers := request.Handlers{} handlers.Sign.PushBack(v4.Sign) // Do we need to use request.New ? Or can we create a raw Request struct and // jus swap out the HTTPRequest with our own existing one? awsReq := request.New(*config, clientInfo, handlers, nil, operation, nil, nil) // Referenced during the execution of awsReq.Sign(): // req.Config.Credentials // req.Config.LogLevel.Value() // req.Config.Logger // req.ClientInfo.SigningRegion (will default to Config.Region) // req.ClientInfo.SigningName (will default to ServiceName) // req.ClientInfo.ServiceName // req.HTTPRequest // req.Time // req.ExpireTime // req.Body // Set the body in the awsReq for calculation of body Digest // iotuil.ReadAll reads the Body from the stream so it can be copied into awsReq // This drains the body from the original (proxied) request. // To fix, we replace req.Body with a copy (NopCloser provides io.ReadCloser interface) buf, _ := ioutil.ReadAll(req.Body) req.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) awsReq.SetBufferBody(buf) // Use the updated req.URL for creating the signed request // We pass the full URL object to include Host, Scheme, and any params awsReq.HTTPRequest.URL = req.URL // These are now set above via req, but it's imperative that this remains // correctly set before calling .Sign() //awsReq.HTTPRequest.URL.Scheme = target.Scheme //awsReq.HTTPRequest.URL.Host = target.Host // Perform the signing, updating awsReq in place if err := awsReq.Sign(); err != nil { fmt.Println(err) } // Write the Signed Headers into the Original Request for k, v := range awsReq.HTTPRequest.Header { req.Header[k] = v } } return &httputil.ReverseProxy{ Director: director, } }
// NewRequest returns a new Request pointer for the service API // operation and parameters. func (s *Service) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request { return request.New(s.ServiceInfo, s.Handlers, s.Retryer, operation, params, data) }