mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-19 22:44:18 +00:00
address comments
This commit is contained in:
@@ -6,13 +6,10 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -210,6 +207,53 @@ func mustNewPresignedRequest(iam *IdentityAccessManagement, method string, urlSt
|
||||
return req
|
||||
}
|
||||
|
||||
// preSignV4 adds presigned URL parameters to the request
|
||||
func preSignV4(iam *IdentityAccessManagement, req *http.Request, accessKey, secretKey string, expires int64) error {
|
||||
// Create credential scope
|
||||
now := time.Now().UTC()
|
||||
dateStr := now.Format(iso8601Format)
|
||||
|
||||
// Create credential header
|
||||
scope := fmt.Sprintf("%s/%s/%s/%s", now.Format(yyyymmdd), "us-east-1", "s3", "aws4_request")
|
||||
credential := fmt.Sprintf("%s/%s", accessKey, scope)
|
||||
|
||||
// Get the query parameters
|
||||
query := req.URL.Query()
|
||||
query.Set("X-Amz-Algorithm", signV4Algorithm)
|
||||
query.Set("X-Amz-Credential", credential)
|
||||
query.Set("X-Amz-Date", dateStr)
|
||||
query.Set("X-Amz-Expires", fmt.Sprintf("%d", expires))
|
||||
query.Set("X-Amz-SignedHeaders", "host")
|
||||
|
||||
// Set the query on the URL (without signature yet)
|
||||
req.URL.RawQuery = query.Encode()
|
||||
|
||||
// Get the payload hash
|
||||
hashedPayload := getContentSha256Cksum(req)
|
||||
|
||||
// Extract signed headers
|
||||
extractedSignedHeaders := make(http.Header)
|
||||
extractedSignedHeaders["host"] = []string{req.Host}
|
||||
|
||||
// Get canonical request
|
||||
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, req.URL.RawQuery, req.URL.Path, req.Method)
|
||||
|
||||
// Get string to sign
|
||||
stringToSign := getStringToSign(canonicalRequest, now, scope)
|
||||
|
||||
// Get signing key
|
||||
signingKey := getSigningKey(secretKey, now.Format(yyyymmdd), "us-east-1", "s3")
|
||||
|
||||
// Calculate signature
|
||||
signature := getSignature(signingKey, stringToSign)
|
||||
|
||||
// Add signature to query
|
||||
query.Set("X-Amz-Signature", signature)
|
||||
req.URL.RawQuery = query.Encode()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns new HTTP request object.
|
||||
func newTestRequest(method, urlStr string, contentLength int64, body io.ReadSeeker) (*http.Request, error) {
|
||||
if method == "" {
|
||||
@@ -459,47 +503,6 @@ func signRequestV4(req *http.Request, accessKey, secretKey string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// preSignV4 presign the request, in accordance with
|
||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html.
|
||||
func preSignV4(iam *IdentityAccessManagement, req *http.Request, accessKeyID, secretAccessKey string, expires int64) error {
|
||||
// Presign is not needed for anonymous credentials.
|
||||
if accessKeyID == "" || secretAccessKey == "" {
|
||||
return errors.New("Presign cannot be generated without access and secret keys")
|
||||
}
|
||||
|
||||
region := "us-east-1"
|
||||
date := time.Now().UTC()
|
||||
scope := getScope(date, region)
|
||||
credential := fmt.Sprintf("%s/%s", accessKeyID, scope)
|
||||
|
||||
// Set URL query.
|
||||
query := req.URL.Query()
|
||||
query.Set("X-Amz-Algorithm", signV4Algorithm)
|
||||
query.Set("X-Amz-Date", date.Format(iso8601Format))
|
||||
query.Set("X-Amz-Expires", strconv.FormatInt(expires, 10))
|
||||
query.Set("X-Amz-SignedHeaders", "host")
|
||||
query.Set("X-Amz-Credential", credential)
|
||||
query.Set("X-Amz-Content-Sha256", unsignedPayload)
|
||||
|
||||
// "host" is the only header required to be signed for Presigned URLs.
|
||||
extractedSignedHeaders := make(http.Header)
|
||||
extractedSignedHeaders.Set("host", req.Host)
|
||||
|
||||
queryStr := strings.Replace(query.Encode(), "+", "%20", -1)
|
||||
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, unsignedPayload, queryStr, req.URL.Path, req.Method)
|
||||
stringToSign := getStringToSign(canonicalRequest, date, scope)
|
||||
signingKey := getSigningKey(secretAccessKey, date.Format(yyyymmdd), region, "s3")
|
||||
signature := getSignature(signingKey, stringToSign)
|
||||
|
||||
req.URL.RawQuery = query.Encode()
|
||||
|
||||
// Add signature header to RawQuery.
|
||||
req.URL.RawQuery += "&X-Amz-Signature=" + url.QueryEscape(signature)
|
||||
|
||||
// Construct the final presigned URL.
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodePath encode the strings from UTF-8 byte representations to HTML hex escape sequences
|
||||
//
|
||||
// This is necessary since regular url.Parse() and url.Encode() functions do not support UTF-8
|
||||
|
||||
Reference in New Issue
Block a user