Example #1
0
func (h *awsAuthHeaderer) SignRequest(r *http.Request) *http.Request {
	region := h.region

	var body io.ReadSeeker
	if r.Body != nil {
		body = r.Body.(io.ReadSeeker)
	}

	if len(region) == 0 {
		region = guessAWSRegion(r.URL.Host)
	}
	v4.Sign(&request.Request{
		ClientInfo: metadata.ClientInfo{
			SigningRegion: region,
			SigningName:   awsS3Service,
		},
		Config: aws.Config{
			Credentials: credentials.NewStaticCredentials(h.accessKeyID, h.secretAccessKey, ""),
		},
		HTTPRequest: r,
		Body:        body,
		Time:        time.Now(),
	})

	return r
}
// SignHTTPRequest signs an http.Request struct with authv4 using the given region, service, and credentials.
func SignHTTPRequest(req *http.Request, region, service string, creds *credentials.Credentials, body io.ReadSeeker) {
	v4.Sign(&request.Request{
		ClientInfo: metadata.ClientInfo{
			SigningRegion: region,
			SigningName:   service,
		},
		Config: aws.Config{
			Credentials: creds,
		},
		HTTPRequest: req,
		Body:        body,
		Time:        time.Now(),
	})
}
func (p *SigningRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	glog.V(2).Infof("Got request: %s %s", req.Method, req.URL)

	// Fix the host header in case broken by proxy-rewrite
	if req.URL.Host != "" {
		req.Host = req.URL.Host
	}

	// I think the AWS authentication proxy does not like forwarded headers
	for k := range req.Header {
		lk := strings.ToLower(k)
		if lk == "x-forwarded-host" {
			delete(req.Header, k)
		}
		if lk == "x-forwarded-for" {
			delete(req.Header, k)
		}
		if lk == "x-forwarded-proto" {
			delete(req.Header, k)
		}
		if lk == "x-forward-for" {
			delete(req.Header, k)
		}
		if lk == "x-forward-proto" {
			delete(req.Header, k)
		}
		if lk == "x-forward-port" {
			delete(req.Header, k)
		}
		if lk == "x-forwarded-port" {
			delete(req.Header, k)
		}
		if lk == "x-forwarded-prefix" {
			delete(req.Header, k)
		}
		if lk == "x-netflix-httpclientname" {
			delete(req.Header, k)
		}
		if lk == "x-newrelic-id" {
			delete(req.Header, k)
		}
		if lk == "x-newrelic-transaction" {
			delete(req.Header, k)
		}
		if lk == "netflix.nfhttpclient.version" {
			delete(req.Header, k)
		}
	}

	// We're going to put our own auth headers on here
	delete(req.Header, "Authorization")

	var body []byte
	var err error

	if req.Body != nil {
		body, err = ioutil.ReadAll(req.Body)
		if err != nil {
			glog.Infof("error reading request body: %v", err)
			return nil, err
		}
	}

	if req.Method == "GET" || req.Method == "HEAD" {
		delete(req.Header, "Content-Length")
	}

	oldPath := req.URL.Path
	if oldPath != "" {
		// Escape the path before signing so that the path in the signature and
		// the path in the request match.
		req.URL.Path = req.URL.EscapedPath()
		glog.V(4).Infof("Path -> %q", req.URL.Path)
	}

	awsReq := &request.Request{}
	awsReq.Config.Credentials = p.credentials
	awsReq.Config.Region = aws.String(p.region)
	awsReq.ClientInfo.ServiceName = SERVICE_NAME
	awsReq.HTTPRequest = req
	awsReq.Time = time.Now()
	awsReq.ExpireTime = 0
	if body != nil {
		awsReq.Body = bytes.NewReader(body)
	}

	if glog.V(4) {
		awsReq.Config.LogLevel = aws.LogLevel(aws.LogDebugWithSigning)
		awsReq.Config.Logger = aws.NewDefaultLogger()
	}

	v4.Sign(awsReq)

	if awsReq.Error != nil {
		glog.Warningf("error signing request: %v", awsReq.Error)
		return nil, awsReq.Error
	}

	req.URL.Path = oldPath

	if body != nil {
		req.Body = ioutil.NopCloser(bytes.NewReader(body))
	}

	response, err := p.inner.RoundTrip(req)

	if err != nil {
		glog.Warning("Request error: ", err)
		return nil, err
	} else {
		glog.V(2).Infof("response %s", response.Status)
		return response, err
	}
}