mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
use ParseForm() to allow query param lookups once (#12900)
``` cpu: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz BenchmarkURLQueryForm BenchmarkURLQueryForm-4 247099363 4.809 ns/op 0 B/op 0 allocs/op BenchmarkURLQuery BenchmarkURLQuery-4 2517624 462.1 ns/op 432 B/op 4 allocs/op PASS ok github.com/minio/minio/cmd 3.848s ```
This commit is contained in:
parent
7b0b0f9101
commit
a2cd3c9a1d
@ -122,7 +122,7 @@ func (a adminAPIHandlers) SetRemoteTargetHandler(w http.ResponseWriter, r *http.
|
|||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
bucket := pathClean(vars["bucket"])
|
bucket := pathClean(vars["bucket"])
|
||||||
update := r.URL.Query().Get("update") == "true"
|
update := r.Form.Get("update") == "true"
|
||||||
|
|
||||||
if !globalIsErasure {
|
if !globalIsErasure {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL)
|
||||||
@ -169,7 +169,7 @@ func (a adminAPIHandlers) SetRemoteTargetHandler(w http.ResponseWriter, r *http.
|
|||||||
target.SourceBucket = bucket
|
target.SourceBucket = bucket
|
||||||
var ops []madmin.TargetUpdateType
|
var ops []madmin.TargetUpdateType
|
||||||
if update {
|
if update {
|
||||||
ops = madmin.GetTargetUpdateOps(r.URL.Query())
|
ops = madmin.GetTargetUpdateOps(r.Form)
|
||||||
} else {
|
} else {
|
||||||
target.Arn = globalBucketTargetSys.getRemoteARN(bucket, &target)
|
target.Arn = globalBucketTargetSys.getRemoteARN(bucket, &target)
|
||||||
}
|
}
|
||||||
|
@ -337,7 +337,7 @@ func (a adminAPIHandlers) HelpConfigKVHandler(w http.ResponseWriter, r *http.Req
|
|||||||
subSys := vars["subSys"]
|
subSys := vars["subSys"]
|
||||||
key := vars["key"]
|
key := vars["key"]
|
||||||
|
|
||||||
_, envOnly := r.URL.Query()["env"]
|
_, envOnly := r.Form["env"]
|
||||||
|
|
||||||
rd, err := GetHelp(subSys, key, envOnly)
|
rd, err := GetHelp(subSys, key, envOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -851,7 +851,7 @@ func (a adminAPIHandlers) ListServiceAccounts(w http.ResponseWriter, r *http.Req
|
|||||||
|
|
||||||
var targetAccount string
|
var targetAccount string
|
||||||
|
|
||||||
user := r.URL.Query().Get("user")
|
user := r.Form.Get("user")
|
||||||
if user != "" {
|
if user != "" {
|
||||||
if !globalIAMSys.IsAllowed(iampolicy.Args{
|
if !globalIAMSys.IsAllowed(iampolicy.Args{
|
||||||
AccountName: cred.AccessKey,
|
AccountName: cred.AccessKey,
|
||||||
@ -997,7 +997,7 @@ func (a adminAPIHandlers) AccountInfoHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
r.Header.Set("delimiter", SlashSeparator)
|
r.Header.Set("delimiter", SlashSeparator)
|
||||||
|
|
||||||
// Check if we are asked to return prefix usage
|
// Check if we are asked to return prefix usage
|
||||||
enablePrefixUsage := r.URL.Query().Get("prefix-usage") == "true"
|
enablePrefixUsage := r.Form.Get("prefix-usage") == "true"
|
||||||
|
|
||||||
isAllowedAccess := func(bucketName string) (rd, wr bool) {
|
isAllowedAccess := func(bucketName string) (rd, wr bool) {
|
||||||
if globalIAMSys.IsAllowed(iampolicy.Args{
|
if globalIAMSys.IsAllowed(iampolicy.Args{
|
||||||
|
@ -450,7 +450,7 @@ func (a adminAPIHandlers) TopLocksHandler(w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
count := 10 // by default list only top 10 entries
|
count := 10 // by default list only top 10 entries
|
||||||
if countStr := r.URL.Query().Get("count"); countStr != "" {
|
if countStr := r.Form.Get("count"); countStr != "" {
|
||||||
var err error
|
var err error
|
||||||
count, err = strconv.Atoi(countStr)
|
count, err = strconv.Atoi(countStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -458,7 +458,7 @@ func (a adminAPIHandlers) TopLocksHandler(w http.ResponseWriter, r *http.Request
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stale := r.URL.Query().Get("stale") == "true" // list also stale locks
|
stale := r.Form.Get("stale") == "true" // list also stale locks
|
||||||
|
|
||||||
peerLocks := globalNotificationSys.GetLocks(ctx, r)
|
peerLocks := globalNotificationSys.GetLocks(ctx, r)
|
||||||
|
|
||||||
@ -713,7 +713,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hip, errCode := extractHealInitParams(mux.Vars(r), r.URL.Query(), r.Body)
|
hip, errCode := extractHealInitParams(mux.Vars(r), r.Form, r.Body)
|
||||||
if errCode != ErrNone {
|
if errCode != ErrNone {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(errCode), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(errCode), r.URL)
|
||||||
return
|
return
|
||||||
@ -926,9 +926,9 @@ func (a adminAPIHandlers) SpeedtestHandler(w http.ResponseWriter, r *http.Reques
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeStr := r.URL.Query().Get(peerRESTSize)
|
sizeStr := r.Form.Get(peerRESTSize)
|
||||||
durationStr := r.URL.Query().Get(peerRESTDuration)
|
durationStr := r.Form.Get(peerRESTDuration)
|
||||||
concurrentStr := r.URL.Query().Get(peerRESTConcurrent)
|
concurrentStr := r.Form.Get(peerRESTConcurrent)
|
||||||
|
|
||||||
size, err := strconv.Atoi(sizeStr)
|
size, err := strconv.Atoi(sizeStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1157,7 +1157,7 @@ func mustTrace(entry interface{}, opts madmin.ServiceTraceOpts) (shouldTrace boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func extractTraceOptions(r *http.Request) (opts madmin.ServiceTraceOpts, err error) {
|
func extractTraceOptions(r *http.Request) (opts madmin.ServiceTraceOpts, err error) {
|
||||||
q := r.URL.Query()
|
q := r.Form
|
||||||
|
|
||||||
opts.OnlyErrors = q.Get("err") == "true"
|
opts.OnlyErrors = q.Get("err") == "true"
|
||||||
opts.S3 = q.Get("s3") == "true"
|
opts.S3 = q.Get("s3") == "true"
|
||||||
@ -1259,15 +1259,15 @@ func (a adminAPIHandlers) ConsoleLogHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node := r.URL.Query().Get("node")
|
node := r.Form.Get("node")
|
||||||
// limit buffered console entries if client requested it.
|
// limit buffered console entries if client requested it.
|
||||||
limitStr := r.URL.Query().Get("limit")
|
limitStr := r.Form.Get("limit")
|
||||||
limitLines, err := strconv.Atoi(limitStr)
|
limitLines, err := strconv.Atoi(limitStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
limitLines = 10
|
limitLines = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
logKind := r.URL.Query().Get("logType")
|
logKind := r.Form.Get("logType")
|
||||||
if logKind == "" {
|
if logKind == "" {
|
||||||
logKind = string(logger.All)
|
logKind = string(logger.All)
|
||||||
}
|
}
|
||||||
@ -1342,7 +1342,7 @@ func (a adminAPIHandlers) KMSCreateKeyHandler(w http.ResponseWriter, r *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := GlobalKMS.CreateKey(r.URL.Query().Get("key-id")); err != nil {
|
if err := GlobalKMS.CreateKey(r.Form.Get("key-id")); err != nil {
|
||||||
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1409,7 +1409,7 @@ func (a adminAPIHandlers) KMSKeyStatusHandler(w http.ResponseWriter, r *http.Req
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
keyID := r.URL.Query().Get("key-id")
|
keyID := r.Form.Get("key-id")
|
||||||
if keyID == "" {
|
if keyID == "" {
|
||||||
keyID = stat.DefaultKey
|
keyID = stat.DefaultKey
|
||||||
}
|
}
|
||||||
@ -1576,7 +1576,7 @@ func (a adminAPIHandlers) HealthInfoHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
query := r.URL.Query()
|
query := r.Form
|
||||||
healthInfo := madmin.HealthInfo{Version: madmin.HealthInfoVersion}
|
healthInfo := madmin.HealthInfo{Version: madmin.HealthInfoVersion}
|
||||||
healthInfoCh := make(chan madmin.HealthInfo)
|
healthInfoCh := make(chan madmin.HealthInfo)
|
||||||
|
|
||||||
@ -1600,7 +1600,7 @@ func (a adminAPIHandlers) HealthInfoHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
}
|
}
|
||||||
|
|
||||||
deadline := 1 * time.Hour
|
deadline := 1 * time.Hour
|
||||||
if dstr := r.URL.Query().Get("deadline"); dstr != "" {
|
if dstr := r.Form.Get("deadline"); dstr != "" {
|
||||||
var err error
|
var err error
|
||||||
deadline, err = time.ParseDuration(dstr)
|
deadline, err = time.ParseDuration(dstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1975,7 +1975,7 @@ func (a adminAPIHandlers) BandwidthMonitorHandler(w http.ResponseWriter, r *http
|
|||||||
reportCh := make(chan madmin.BucketBandwidthReport)
|
reportCh := make(chan madmin.BucketBandwidthReport)
|
||||||
keepAliveTicker := time.NewTicker(500 * time.Millisecond)
|
keepAliveTicker := time.NewTicker(500 * time.Millisecond)
|
||||||
defer keepAliveTicker.Stop()
|
defer keepAliveTicker.Stop()
|
||||||
bucketsRequestedString := r.URL.Query().Get("buckets")
|
bucketsRequestedString := r.Form.Get("buckets")
|
||||||
bucketsRequested := strings.Split(bucketsRequestedString, ",")
|
bucketsRequested := strings.Split(bucketsRequestedString, ",")
|
||||||
go func() {
|
go func() {
|
||||||
defer close(reportCh)
|
defer close(reportCh)
|
||||||
@ -2233,8 +2233,8 @@ func (a adminAPIHandlers) InspectDataHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
volume := r.URL.Query().Get("volume")
|
volume := r.Form.Get("volume")
|
||||||
file := r.URL.Query().Get("file")
|
file := r.Form.Get("file")
|
||||||
if len(volume) == 0 {
|
if len(volume) == 0 {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidBucketName), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidBucketName), r.URL)
|
||||||
return
|
return
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@ -61,13 +62,13 @@ func isRequestSignatureV2(r *http.Request) bool {
|
|||||||
|
|
||||||
// Verify if request has AWS PreSign Version '4'.
|
// Verify if request has AWS PreSign Version '4'.
|
||||||
func isRequestPresignedSignatureV4(r *http.Request) bool {
|
func isRequestPresignedSignatureV4(r *http.Request) bool {
|
||||||
_, ok := r.URL.Query()[xhttp.AmzCredential]
|
_, ok := r.Form[xhttp.AmzCredential]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify request has AWS PreSign Version '2'.
|
// Verify request has AWS PreSign Version '2'.
|
||||||
func isRequestPresignedSignatureV2(r *http.Request) bool {
|
func isRequestPresignedSignatureV2(r *http.Request) bool {
|
||||||
_, ok := r.URL.Query()[xhttp.AmzAccessKeyID]
|
_, ok := r.Form[xhttp.AmzAccessKeyID]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +103,14 @@ const (
|
|||||||
|
|
||||||
// Get request authentication type.
|
// Get request authentication type.
|
||||||
func getRequestAuthType(r *http.Request) authType {
|
func getRequestAuthType(r *http.Request) authType {
|
||||||
|
if r.URL != nil {
|
||||||
|
var err error
|
||||||
|
r.Form, err = url.ParseQuery(r.URL.RawQuery)
|
||||||
|
if err != nil {
|
||||||
|
logger.LogIf(r.Context(), err)
|
||||||
|
return authTypeUnknown
|
||||||
|
}
|
||||||
|
}
|
||||||
if isRequestSignatureV2(r) {
|
if isRequestSignatureV2(r) {
|
||||||
return authTypeSignedV2
|
return authTypeSignedV2
|
||||||
} else if isRequestPresignedSignatureV2(r) {
|
} else if isRequestPresignedSignatureV2(r) {
|
||||||
@ -116,7 +125,7 @@ func getRequestAuthType(r *http.Request) authType {
|
|||||||
return authTypeJWT
|
return authTypeJWT
|
||||||
} else if isRequestPostPolicySignatureV4(r) {
|
} else if isRequestPostPolicySignatureV4(r) {
|
||||||
return authTypePostPolicy
|
return authTypePostPolicy
|
||||||
} else if _, ok := r.URL.Query()[xhttp.Action]; ok {
|
} else if _, ok := r.Form[xhttp.Action]; ok {
|
||||||
return authTypeSTS
|
return authTypeSTS
|
||||||
} else if _, ok := r.Header[xhttp.Authorization]; !ok {
|
} else if _, ok := r.Header[xhttp.Authorization]; !ok {
|
||||||
return authTypeAnonymous
|
return authTypeAnonymous
|
||||||
@ -183,7 +192,7 @@ func getSessionToken(r *http.Request) (token string) {
|
|||||||
if token != "" {
|
if token != "" {
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
return r.URL.Query().Get(xhttp.AmzSecurityToken)
|
return r.Form.Get(xhttp.AmzSecurityToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch claims in the security token returned by the client, doesn't return
|
// Fetch claims in the security token returned by the client, doesn't return
|
||||||
@ -444,7 +453,7 @@ func isReqAuthenticated(ctx context.Context, r *http.Request, region string, sty
|
|||||||
// Do not verify 'X-Amz-Content-Sha256' if skipSHA256.
|
// Do not verify 'X-Amz-Content-Sha256' if skipSHA256.
|
||||||
var contentSHA256 []byte
|
var contentSHA256 []byte
|
||||||
if skipSHA256 := skipContentSha256Cksum(r); !skipSHA256 && isRequestPresignedSignatureV4(r) {
|
if skipSHA256 := skipContentSha256Cksum(r); !skipSHA256 && isRequestPresignedSignatureV4(r) {
|
||||||
if sha256Sum, ok := r.URL.Query()[xhttp.AmzContentSha256]; ok && len(sha256Sum) > 0 {
|
if sha256Sum, ok := r.Form[xhttp.AmzContentSha256]; ok && len(sha256Sum) > 0 {
|
||||||
contentSHA256, err = hex.DecodeString(sha256Sum[0])
|
contentSHA256, err = hex.DecodeString(sha256Sum[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrContentSHA256Mismatch
|
return ErrContentSHA256Mismatch
|
||||||
|
@ -38,6 +38,7 @@ func TestGetRequestAuthType(t *testing.T) {
|
|||||||
req *http.Request
|
req *http.Request
|
||||||
authT authType
|
authT authType
|
||||||
}
|
}
|
||||||
|
nopCloser := ioutil.NopCloser(io.LimitReader(&nullReader{}, 1024))
|
||||||
testCases := []testCase{
|
testCases := []testCase{
|
||||||
// Test case - 1
|
// Test case - 1
|
||||||
// Check for generic signature v4 header.
|
// Check for generic signature v4 header.
|
||||||
@ -54,6 +55,7 @@ func TestGetRequestAuthType(t *testing.T) {
|
|||||||
"Content-Encoding": []string{streamingContentEncoding},
|
"Content-Encoding": []string{streamingContentEncoding},
|
||||||
},
|
},
|
||||||
Method: http.MethodPut,
|
Method: http.MethodPut,
|
||||||
|
Body: nopCloser,
|
||||||
},
|
},
|
||||||
authT: authTypeStreamingSigned,
|
authT: authTypeStreamingSigned,
|
||||||
},
|
},
|
||||||
@ -113,6 +115,7 @@ func TestGetRequestAuthType(t *testing.T) {
|
|||||||
"Content-Type": []string{"multipart/form-data"},
|
"Content-Type": []string{"multipart/form-data"},
|
||||||
},
|
},
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
|
Body: nopCloser,
|
||||||
},
|
},
|
||||||
authT: authTypePostPolicy,
|
authT: authTypePostPolicy,
|
||||||
},
|
},
|
||||||
@ -220,6 +223,7 @@ func TestIsRequestPresignedSignatureV2(t *testing.T) {
|
|||||||
q := inputReq.URL.Query()
|
q := inputReq.URL.Query()
|
||||||
q.Add(testCase.inputQueryKey, testCase.inputQueryValue)
|
q.Add(testCase.inputQueryKey, testCase.inputQueryValue)
|
||||||
inputReq.URL.RawQuery = q.Encode()
|
inputReq.URL.RawQuery = q.Encode()
|
||||||
|
inputReq.ParseForm()
|
||||||
|
|
||||||
actualResult := isRequestPresignedSignatureV2(inputReq)
|
actualResult := isRequestPresignedSignatureV2(inputReq)
|
||||||
if testCase.expectedResult != actualResult {
|
if testCase.expectedResult != actualResult {
|
||||||
@ -254,6 +258,7 @@ func TestIsRequestPresignedSignatureV4(t *testing.T) {
|
|||||||
q := inputReq.URL.Query()
|
q := inputReq.URL.Query()
|
||||||
q.Add(testCase.inputQueryKey, testCase.inputQueryValue)
|
q.Add(testCase.inputQueryKey, testCase.inputQueryValue)
|
||||||
inputReq.URL.RawQuery = q.Encode()
|
inputReq.URL.RawQuery = q.Encode()
|
||||||
|
inputReq.ParseForm()
|
||||||
|
|
||||||
actualResult := isRequestPresignedSignatureV4(inputReq)
|
actualResult := isRequestPresignedSignatureV4(inputReq)
|
||||||
if testCase.expectedResult != actualResult {
|
if testCase.expectedResult != actualResult {
|
||||||
|
@ -246,7 +246,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix, keyMarker, uploadIDMarker, delimiter, maxUploads, encodingType, errCode := getBucketMultipartResources(r.URL.Query())
|
prefix, keyMarker, uploadIDMarker, delimiter, maxUploads, encodingType, errCode := getBucketMultipartResources(r.Form)
|
||||||
if errCode != ErrNone {
|
if errCode != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(errCode), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(errCode), r.URL)
|
||||||
return
|
return
|
||||||
@ -1699,7 +1699,7 @@ func (api objectAPIHandlers) ResetBucketReplicationStateHandler(w http.ResponseW
|
|||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
bucket := vars["bucket"]
|
bucket := vars["bucket"]
|
||||||
durationStr := r.URL.Query().Get("older-than")
|
durationStr := r.Form.Get("older-than")
|
||||||
var (
|
var (
|
||||||
days time.Duration
|
days time.Duration
|
||||||
err error
|
err error
|
||||||
|
@ -458,7 +458,7 @@ func (r *RestoreObjectRequest) validate(ctx context.Context, objAPI ObjectLayer)
|
|||||||
func postRestoreOpts(ctx context.Context, r *http.Request, bucket, object string) (opts ObjectOptions, err error) {
|
func postRestoreOpts(ctx context.Context, r *http.Request, bucket, object string) (opts ObjectOptions, err error) {
|
||||||
versioned := globalBucketVersioningSys.Enabled(bucket)
|
versioned := globalBucketVersioningSys.Enabled(bucket)
|
||||||
versionSuspended := globalBucketVersioningSys.Suspended(bucket)
|
versionSuspended := globalBucketVersioningSys.Suspended(bucket)
|
||||||
vid := strings.TrimSpace(r.URL.Query().Get(xhttp.VersionID))
|
vid := strings.TrimSpace(r.Form.Get(xhttp.VersionID))
|
||||||
if vid != "" && vid != nullVersionID {
|
if vid != "" && vid != nullVersionID {
|
||||||
_, err := uuid.Parse(vid)
|
_, err := uuid.Parse(vid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -92,7 +92,7 @@ func (api objectAPIHandlers) ListObjectVersionsHandler(w http.ResponseWriter, r
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
urlValues := r.URL.Query()
|
urlValues := r.Form
|
||||||
|
|
||||||
// Extract all the listBucketVersions query params to their native values.
|
// Extract all the listBucketVersions query params to their native values.
|
||||||
prefix, marker, delimiter, maxkeys, encodingType, versionIDMarker, errCode := getListBucketObjectVersionsArgs(urlValues)
|
prefix, marker, delimiter, maxkeys, encodingType, versionIDMarker, errCode := getListBucketObjectVersionsArgs(urlValues)
|
||||||
@ -153,7 +153,7 @@ func (api objectAPIHandlers) ListObjectsV2MHandler(w http.ResponseWriter, r *htt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
urlValues := r.URL.Query()
|
urlValues := r.Form
|
||||||
|
|
||||||
// Extract all the listObjectsV2 query params to their native values.
|
// Extract all the listObjectsV2 query params to their native values.
|
||||||
prefix, token, startAfter, delimiter, fetchOwner, maxKeys, encodingType, errCode := getListObjectsV2Args(urlValues)
|
prefix, token, startAfter, delimiter, fetchOwner, maxKeys, encodingType, errCode := getListObjectsV2Args(urlValues)
|
||||||
@ -220,7 +220,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
urlValues := r.URL.Query()
|
urlValues := r.Form
|
||||||
|
|
||||||
// Extract all the listObjectsV2 query params to their native values.
|
// Extract all the listObjectsV2 query params to their native values.
|
||||||
prefix, token, startAfter, delimiter, fetchOwner, maxKeys, encodingType, errCode := getListObjectsV2Args(urlValues)
|
prefix, token, startAfter, delimiter, fetchOwner, maxKeys, encodingType, errCode := getListObjectsV2Args(urlValues)
|
||||||
@ -329,7 +329,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract all the litsObjectsV1 query params to their native values.
|
// Extract all the litsObjectsV1 query params to their native values.
|
||||||
prefix, marker, delimiter, maxKeys, encodingType, s3Error := getListObjectsV1Args(r.URL.Query())
|
prefix, marker, delimiter, maxKeys, encodingType, s3Error := getListObjectsV1Args(r.Form)
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
||||||
return
|
return
|
||||||
|
@ -77,10 +77,10 @@ func getConditionValues(r *http.Request, lc string, username string, claims map[
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vid := r.URL.Query().Get("versionId")
|
vid := r.Form.Get(xhttp.VersionID)
|
||||||
if vid == "" {
|
if vid == "" {
|
||||||
if u, err := url.Parse(r.Header.Get(xhttp.AmzCopySource)); err == nil {
|
if u, err := url.Parse(r.Header.Get(xhttp.AmzCopySource)); err == nil {
|
||||||
vid = u.Query().Get("versionId")
|
vid = u.Query().Get(xhttp.VersionID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,8 +143,8 @@ func getConditionValues(r *http.Request, lc string, username string, claims map[
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cloneURLValues = url.Values{}
|
cloneURLValues := make(url.Values, len(r.Form))
|
||||||
for k, v := range r.URL.Query() {
|
for k, v := range r.Form {
|
||||||
cloneURLValues[k] = v
|
cloneURLValues[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
// Test cross domain xml handler.
|
// Test cross domain xml handler.
|
||||||
func TestCrossXMLHandler(t *testing.T) {
|
func TestCrossXMLHandler(t *testing.T) {
|
||||||
// Server initialization.
|
// Server initialization.
|
||||||
router := mux.NewRouter().SkipClean(true)
|
router := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
||||||
handler := setCrossDomainPolicy(router)
|
handler := setCrossDomainPolicy(router)
|
||||||
srv := httptest.NewServer(handler)
|
srv := httptest.NewServer(handler)
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@ func setRequestValidityHandler(h http.Handler) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Check for bad components in URL query values.
|
// Check for bad components in URL query values.
|
||||||
for _, vv := range r.URL.Query() {
|
for _, vv := range r.Form {
|
||||||
for _, v := range vv {
|
for _, v := range vv {
|
||||||
if hasBadPathComponent(v) {
|
if hasBadPathComponent(v) {
|
||||||
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL)
|
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL)
|
||||||
@ -436,55 +436,6 @@ func setBucketForwardingHandler(h http.Handler) http.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// For browser requests, when federation is setup we need to
|
|
||||||
// specifically handle download and upload for browser requests.
|
|
||||||
if guessIsBrowserReq(r) {
|
|
||||||
var bucket, _ string
|
|
||||||
switch r.Method {
|
|
||||||
case http.MethodPut:
|
|
||||||
if getRequestAuthType(r) == authTypeJWT {
|
|
||||||
bucket, _ = path2BucketObjectWithBasePath(minioReservedBucketPath+"/upload", r.URL.Path)
|
|
||||||
}
|
|
||||||
case http.MethodGet:
|
|
||||||
if t := r.URL.Query().Get("token"); t != "" {
|
|
||||||
bucket, _ = path2BucketObjectWithBasePath(minioReservedBucketPath+"/download", r.URL.Path)
|
|
||||||
} else if getRequestAuthType(r) != authTypeJWT && !strings.HasPrefix(r.URL.Path, minioReservedBucketPath) {
|
|
||||||
bucket, _ = request2BucketObjectName(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if bucket == "" {
|
|
||||||
h.ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sr, err := globalDNSConfig.Get(bucket)
|
|
||||||
if err != nil {
|
|
||||||
if err == dns.ErrNoEntriesFound {
|
|
||||||
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrNoSuchBucket),
|
|
||||||
r.URL)
|
|
||||||
} else {
|
|
||||||
writeErrorResponse(r.Context(), w, toAPIError(r.Context(), err),
|
|
||||||
r.URL)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if globalDomainIPs.Intersection(set.CreateStringSet(getHostsSlice(sr)...)).IsEmpty() {
|
|
||||||
r.URL.Scheme = "http"
|
|
||||||
if globalIsTLS {
|
|
||||||
r.URL.Scheme = "https"
|
|
||||||
}
|
|
||||||
r.URL.Host = getHostFromSrv(sr)
|
|
||||||
// Make sure we remove any existing headers before
|
|
||||||
// proxying the request to another node.
|
|
||||||
for k := range w.Header() {
|
|
||||||
w.Header().Del(k)
|
|
||||||
}
|
|
||||||
globalForwarder.ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
bucket, object := request2BucketObjectName(r)
|
bucket, object := request2BucketObjectName(r)
|
||||||
|
|
||||||
// Requests in federated setups for STS type calls which are
|
// Requests in federated setups for STS type calls which are
|
||||||
|
@ -112,7 +112,7 @@ var userMetadataKeyPrefixes = []string{
|
|||||||
|
|
||||||
// extractMetadata extracts metadata from HTTP header and HTTP queryString.
|
// extractMetadata extracts metadata from HTTP header and HTTP queryString.
|
||||||
func extractMetadata(ctx context.Context, r *http.Request) (metadata map[string]string, err error) {
|
func extractMetadata(ctx context.Context, r *http.Request) (metadata map[string]string, err error) {
|
||||||
query := r.URL.Query()
|
query := r.Form
|
||||||
header := r.Header
|
header := r.Header
|
||||||
metadata = make(map[string]string)
|
metadata = make(map[string]string)
|
||||||
// Extract all query values.
|
// Extract all query values.
|
||||||
|
@ -42,7 +42,7 @@ func ClusterCheckHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
ctx, cancel := context.WithTimeout(ctx, globalAPIConfig.getClusterDeadline())
|
ctx, cancel := context.WithTimeout(ctx, globalAPIConfig.getClusterDeadline())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
opts := HealthOptions{Maintenance: r.URL.Query().Get("maintenance") == "true"}
|
opts := HealthOptions{Maintenance: r.Form.Get("maintenance") == "true"}
|
||||||
result := objLayer.Health(ctx, opts)
|
result := objLayer.Health(ctx, opts)
|
||||||
if result.WriteQuorum > 0 {
|
if result.WriteQuorum > 0 {
|
||||||
w.Header().Set(xhttp.MinIOWriteQuorum, strconv.Itoa(result.WriteQuorum))
|
w.Header().Set(xhttp.MinIOWriteQuorum, strconv.Itoa(result.WriteQuorum))
|
||||||
|
@ -65,7 +65,7 @@ func (api objectAPIHandlers) ListenNotificationHandler(w http.ResponseWriter, r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
values := r.URL.Query()
|
values := r.Form
|
||||||
|
|
||||||
var prefix string
|
var prefix string
|
||||||
if len(values[peerRESTListenPrefix]) > 1 {
|
if len(values[peerRESTListenPrefix]) > 1 {
|
||||||
|
@ -63,15 +63,16 @@ func (l *lockRESTServer) IsValid(w http.ResponseWriter, r *http.Request) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getLockArgs(r *http.Request) (args dsync.LockArgs, err error) {
|
func getLockArgs(r *http.Request) (args dsync.LockArgs, err error) {
|
||||||
quorum, err := strconv.Atoi(r.URL.Query().Get(lockRESTQuorum))
|
values := r.Form
|
||||||
|
quorum, err := strconv.Atoi(values.Get(lockRESTQuorum))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return args, err
|
return args, err
|
||||||
}
|
}
|
||||||
|
|
||||||
args = dsync.LockArgs{
|
args = dsync.LockArgs{
|
||||||
Owner: r.URL.Query().Get(lockRESTOwner),
|
Owner: values.Get(lockRESTOwner),
|
||||||
UID: r.URL.Query().Get(lockRESTUID),
|
UID: values.Get(lockRESTUID),
|
||||||
Source: r.URL.Query().Get(lockRESTSource),
|
Source: values.Get(lockRESTSource),
|
||||||
Quorum: quorum,
|
Quorum: quorum,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,8 +332,8 @@ func (s *storageRESTServer) WalkDirHandler(w http.ResponseWriter, r *http.Reques
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix := r.URL.Query().Get(storageRESTPrefixFilter)
|
prefix := r.Form.Get(storageRESTPrefixFilter)
|
||||||
forward := r.URL.Query().Get(storageRESTForwardFilter)
|
forward := r.Form.Get(storageRESTForwardFilter)
|
||||||
writer := streamHTTPResponse(w)
|
writer := streamHTTPResponse(w)
|
||||||
writer.CloseWithError(s.storage.WalkDir(r.Context(), WalkDirOptions{
|
writer.CloseWithError(s.storage.WalkDir(r.Context(), WalkDirOptions{
|
||||||
Bucket: volume,
|
Bucket: volume,
|
||||||
|
@ -83,7 +83,7 @@ func getOpts(ctx context.Context, r *http.Request, bucket, object string) (Objec
|
|||||||
|
|
||||||
var partNumber int
|
var partNumber int
|
||||||
var err error
|
var err error
|
||||||
if pn := r.URL.Query().Get(xhttp.PartNumber); pn != "" {
|
if pn := r.Form.Get(xhttp.PartNumber); pn != "" {
|
||||||
partNumber, err = strconv.Atoi(pn)
|
partNumber, err = strconv.Atoi(pn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return opts, err
|
return opts, err
|
||||||
@ -93,7 +93,7 @@ func getOpts(ctx context.Context, r *http.Request, bucket, object string) (Objec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vid := strings.TrimSpace(r.URL.Query().Get(xhttp.VersionID))
|
vid := strings.TrimSpace(r.Form.Get(xhttp.VersionID))
|
||||||
if vid != "" && vid != nullVersionID {
|
if vid != "" && vid != nullVersionID {
|
||||||
_, err := uuid.Parse(vid)
|
_, err := uuid.Parse(vid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -219,7 +219,7 @@ func delOpts(ctx context.Context, r *http.Request, bucket, object string) (opts
|
|||||||
// get ObjectOptions for PUT calls from encryption headers and metadata
|
// get ObjectOptions for PUT calls from encryption headers and metadata
|
||||||
func putOpts(ctx context.Context, r *http.Request, bucket, object string, metadata map[string]string) (opts ObjectOptions, err error) {
|
func putOpts(ctx context.Context, r *http.Request, bucket, object string, metadata map[string]string) (opts ObjectOptions, err error) {
|
||||||
versioned := globalBucketVersioningSys.Enabled(bucket)
|
versioned := globalBucketVersioningSys.Enabled(bucket)
|
||||||
vid := strings.TrimSpace(r.URL.Query().Get(xhttp.VersionID))
|
vid := strings.TrimSpace(r.Form.Get(xhttp.VersionID))
|
||||||
if vid != "" && vid != nullVersionID {
|
if vid != "" && vid != nullVersionID {
|
||||||
_, err := uuid.Parse(vid)
|
_, err := uuid.Parse(vid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -491,7 +491,7 @@ func (api objectAPIHandlers) getObjectHandler(ctx context.Context, objectAPI Obj
|
|||||||
setPartsCountHeaders(w, objInfo)
|
setPartsCountHeaders(w, objInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
setHeadGetRespHeaders(w, r.URL.Query())
|
setHeadGetRespHeaders(w, r.Form)
|
||||||
|
|
||||||
statusCodeWritten := false
|
statusCodeWritten := false
|
||||||
httpWriter := ioutil.WriteOnClose(w)
|
httpWriter := ioutil.WriteOnClose(w)
|
||||||
@ -739,7 +739,7 @@ func (api objectAPIHandlers) headObjectHandler(ctx context.Context, objectAPI Ob
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set any additional requested response headers.
|
// Set any additional requested response headers.
|
||||||
setHeadGetRespHeaders(w, r.URL.Query())
|
setHeadGetRespHeaders(w, r.Form)
|
||||||
|
|
||||||
// Successful response.
|
// Successful response.
|
||||||
if rs != nil || opts.PartNumber > 0 {
|
if rs != nil || opts.PartNumber > 0 {
|
||||||
@ -806,7 +806,7 @@ func getCpObjMetadataFromHeader(ctx context.Context, r *http.Request, userMeta m
|
|||||||
// to the destination metadata.
|
// to the destination metadata.
|
||||||
sc := r.Header.Get(xhttp.AmzStorageClass)
|
sc := r.Header.Get(xhttp.AmzStorageClass)
|
||||||
if sc == "" {
|
if sc == "" {
|
||||||
sc = r.URL.Query().Get(xhttp.AmzStorageClass)
|
sc = r.Form.Get(xhttp.AmzStorageClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if x-amz-metadata-directive says REPLACE then
|
// if x-amz-metadata-directive says REPLACE then
|
||||||
@ -2264,8 +2264,8 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadID := r.URL.Query().Get(xhttp.UploadID)
|
uploadID := r.Form.Get(xhttp.UploadID)
|
||||||
partIDString := r.URL.Query().Get(xhttp.PartNumber)
|
partIDString := r.Form.Get(xhttp.PartNumber)
|
||||||
|
|
||||||
partID, err := strconv.Atoi(partIDString)
|
partID, err := strconv.Atoi(partIDString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2591,8 +2591,8 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadID := r.URL.Query().Get(xhttp.UploadID)
|
uploadID := r.Form.Get(xhttp.UploadID)
|
||||||
partIDString := r.URL.Query().Get(xhttp.PartNumber)
|
partIDString := r.Form.Get(xhttp.PartNumber)
|
||||||
|
|
||||||
partID, err := strconv.Atoi(partIDString)
|
partID, err := strconv.Atoi(partIDString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2812,7 +2812,7 @@ func (api objectAPIHandlers) AbortMultipartUploadHandler(w http.ResponseWriter,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadID, _, _, _, s3Error := getObjectResources(r.URL.Query())
|
uploadID, _, _, _, s3Error := getObjectResources(r.Form)
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
||||||
return
|
return
|
||||||
@ -2851,7 +2851,7 @@ func (api objectAPIHandlers) ListObjectPartsHandler(w http.ResponseWriter, r *ht
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadID, partNumberMarker, maxParts, encodingType, s3Error := getObjectResources(r.URL.Query())
|
uploadID, partNumberMarker, maxParts, encodingType, s3Error := getObjectResources(r.Form)
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
||||||
return
|
return
|
||||||
@ -2997,7 +2997,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get upload id.
|
// Get upload id.
|
||||||
uploadID, _, _, _, s3Error := getObjectResources(r.URL.Query())
|
uploadID, _, _, _, s3Error := getObjectResources(r.Form)
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL)
|
||||||
return
|
return
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -557,12 +558,8 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
|
|||||||
t.Fatalf("Test %d: %s: Failed parsing response body: <ERROR> %v", i+1, instanceType, err)
|
t.Fatalf("Test %d: %s: Failed parsing response body: <ERROR> %v", i+1, instanceType, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualError.BucketName != testCase.bucketName {
|
if path.Clean(actualError.Resource) != pathJoin(SlashSeparator, testCase.bucketName, testCase.objectName) {
|
||||||
t.Fatalf("Test %d: %s: Unexpected bucket name, expected %s, got %s", i+1, instanceType, testCase.bucketName, actualError.BucketName)
|
t.Fatalf("Test %d: %s: Unexpected resource, expected %s, got %s", i+1, instanceType, pathJoin(SlashSeparator, testCase.bucketName, testCase.objectName), actualError.Resource)
|
||||||
}
|
|
||||||
|
|
||||||
if actualError.Key != testCase.objectName {
|
|
||||||
t.Fatalf("Test %d: %s: Unexpected object name, expected %s, got %s", i+1, instanceType, testCase.objectName, actualError.Key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify response of the V2 signed HTTP request.
|
// Verify response of the V2 signed HTTP request.
|
||||||
@ -606,12 +603,8 @@ func testAPIGetObjectHandler(obj ObjectLayer, instanceType, bucketName string, a
|
|||||||
t.Fatalf("Test %d: %s: Failed parsing response body: <ERROR> %v", i+1, instanceType, err)
|
t.Fatalf("Test %d: %s: Failed parsing response body: <ERROR> %v", i+1, instanceType, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualError.BucketName != testCase.bucketName {
|
if path.Clean(actualError.Resource) != pathJoin(SlashSeparator, testCase.bucketName, testCase.objectName) {
|
||||||
t.Fatalf("Test %d: %s: Unexpected bucket name, expected %s, got %s", i+1, instanceType, testCase.bucketName, actualError.BucketName)
|
t.Fatalf("Test %d: %s: Unexpected resource, expected %s, got %s", i+1, instanceType, pathJoin(SlashSeparator, testCase.bucketName, testCase.objectName), actualError.Resource)
|
||||||
}
|
|
||||||
|
|
||||||
if actualError.Key != testCase.objectName {
|
|
||||||
t.Fatalf("Test %d: %s: Unexpected object name, expected %s, got %s", i+1, instanceType, testCase.objectName, actualError.Key)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,7 +911,6 @@ func testAPIGetObjectWithPartNumberHandler(obj ObjectLayer, instanceType, bucket
|
|||||||
|
|
||||||
mkGetReqWithPartNumber := func(oindex int, oi ObjectInput, partNumber int) {
|
mkGetReqWithPartNumber := func(oindex int, oi ObjectInput, partNumber int) {
|
||||||
object := oi.objectName
|
object := oi.objectName
|
||||||
rec := httptest.NewRecorder()
|
|
||||||
|
|
||||||
queries := url.Values{}
|
queries := url.Values{}
|
||||||
queries.Add("partNumber", strconv.Itoa(partNumber))
|
queries.Add("partNumber", strconv.Itoa(partNumber))
|
||||||
@ -930,6 +922,7 @@ func testAPIGetObjectWithPartNumberHandler(obj ObjectLayer, instanceType, bucket
|
|||||||
object, oindex, partNumber, err)
|
object, oindex, partNumber, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
apiRouter.ServeHTTP(rec, req)
|
apiRouter.ServeHTTP(rec, req)
|
||||||
|
|
||||||
// Check response code (we make only valid requests in this test)
|
// Check response code (we make only valid requests in this test)
|
||||||
|
@ -136,7 +136,7 @@ func (s *peerRESTServer) LoadPolicyMappingHandler(w http.ResponseWriter, r *http
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, isGroup := r.URL.Query()[peerRESTIsGroup]
|
_, isGroup := r.Form[peerRESTIsGroup]
|
||||||
if err := globalIAMSys.LoadPolicyMapping(objAPI, userOrGroup, isGroup); err != nil {
|
if err := globalIAMSys.LoadPolicyMapping(objAPI, userOrGroup, isGroup); err != nil {
|
||||||
s.writeErrorResponse(w, err)
|
s.writeErrorResponse(w, err)
|
||||||
return
|
return
|
||||||
@ -841,7 +841,7 @@ func (s *peerRESTServer) ListenHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
values := r.URL.Query()
|
values := r.Form
|
||||||
|
|
||||||
var prefix string
|
var prefix string
|
||||||
if len(values[peerRESTListenPrefix]) > 1 {
|
if len(values[peerRESTListenPrefix]) > 1 {
|
||||||
@ -932,15 +932,13 @@ func (s *peerRESTServer) ListenHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func extractTraceOptsFromPeerRequest(r *http.Request) (opts madmin.ServiceTraceOpts, err error) {
|
func extractTraceOptsFromPeerRequest(r *http.Request) (opts madmin.ServiceTraceOpts, err error) {
|
||||||
|
opts.S3 = r.Form.Get(peerRESTTraceS3) == "true"
|
||||||
|
opts.OS = r.Form.Get(peerRESTTraceOS) == "true"
|
||||||
|
opts.Storage = r.Form.Get(peerRESTTraceStorage) == "true"
|
||||||
|
opts.Internal = r.Form.Get(peerRESTTraceInternal) == "true"
|
||||||
|
opts.OnlyErrors = r.Form.Get(peerRESTTraceErr) == "true"
|
||||||
|
|
||||||
q := r.URL.Query()
|
if t := r.Form.Get(peerRESTTraceThreshold); t != "" {
|
||||||
opts.OnlyErrors = q.Get(peerRESTTraceErr) == "true"
|
|
||||||
opts.Storage = q.Get(peerRESTTraceStorage) == "true"
|
|
||||||
opts.Internal = q.Get(peerRESTTraceInternal) == "true"
|
|
||||||
opts.S3 = q.Get(peerRESTTraceS3) == "true"
|
|
||||||
opts.OS = q.Get(peerRESTTraceOS) == "true"
|
|
||||||
|
|
||||||
if t := q.Get(peerRESTTraceThreshold); t != "" {
|
|
||||||
d, err := time.ParseDuration(t)
|
d, err := time.ParseDuration(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return opts, err
|
return opts, err
|
||||||
@ -1078,7 +1076,8 @@ func (s *peerRESTServer) GetBandwidth(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.writeErrorResponse(w, errors.New("invalid request"))
|
s.writeErrorResponse(w, errors.New("invalid request"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bucketsString := r.URL.Query().Get("buckets")
|
|
||||||
|
bucketsString := r.Form.Get("buckets")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
w.(http.Flusher).Flush()
|
w.(http.Flusher).Flush()
|
||||||
|
|
||||||
@ -1259,9 +1258,9 @@ func (s *peerRESTServer) SpeedtestHandler(w http.ResponseWriter, r *http.Request
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeStr := r.URL.Query().Get(peerRESTSize)
|
sizeStr := r.Form.Get(peerRESTSize)
|
||||||
durationStr := r.URL.Query().Get(peerRESTDuration)
|
durationStr := r.Form.Get(peerRESTDuration)
|
||||||
concurrentStr := r.URL.Query().Get(peerRESTConcurrent)
|
concurrentStr := r.Form.Get(peerRESTConcurrent)
|
||||||
|
|
||||||
size, err := strconv.Atoi(sizeStr)
|
size, err := strconv.Atoi(sizeStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -196,7 +196,7 @@ func (api objectAPIHandlers) getObjectInArchiveFileHandler(ctx context.Context,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setHeadGetRespHeaders(w, r.URL.Query())
|
setHeadGetRespHeaders(w, r.Form)
|
||||||
|
|
||||||
httpWriter := ioutil.WriteOnClose(w)
|
httpWriter := ioutil.WriteOnClose(w)
|
||||||
|
|
||||||
@ -467,7 +467,7 @@ func (api objectAPIHandlers) headObjectInArchiveFileHandler(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set any additional requested response headers.
|
// Set any additional requested response headers.
|
||||||
setHeadGetRespHeaders(w, r.URL.Query())
|
setHeadGetRespHeaders(w, r.Form)
|
||||||
|
|
||||||
// Successful response.
|
// Successful response.
|
||||||
if rs != nil {
|
if rs != nil {
|
||||||
|
@ -183,7 +183,7 @@ func doesPresignV2SignatureMatch(r *http.Request) APIErrorCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getReqAccessKeyV2(r *http.Request) (auth.Credentials, bool, APIErrorCode) {
|
func getReqAccessKeyV2(r *http.Request) (auth.Credentials, bool, APIErrorCode) {
|
||||||
if accessKey := r.URL.Query().Get(xhttp.AmzAccessKeyID); accessKey != "" {
|
if accessKey := r.Form.Get(xhttp.AmzAccessKeyID); accessKey != "" {
|
||||||
return checkKeyValid(accessKey)
|
return checkKeyValid(accessKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ func (c credentialHeader) getScope() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getReqAccessKeyV4(r *http.Request, region string, stype serviceType) (auth.Credentials, bool, APIErrorCode) {
|
func getReqAccessKeyV4(r *http.Request, region string, stype serviceType) (auth.Credentials, bool, APIErrorCode) {
|
||||||
ch, s3Err := parseCredentialHeader("Credential="+r.URL.Query().Get(xhttp.AmzCredential), region, stype)
|
ch, s3Err := parseCredentialHeader("Credential="+r.Form.Get(xhttp.AmzCredential), region, stype)
|
||||||
if s3Err != ErrNone {
|
if s3Err != ErrNone {
|
||||||
// Strip off the Algorithm prefix.
|
// Strip off the Algorithm prefix.
|
||||||
v4Auth := strings.TrimPrefix(r.Header.Get("Authorization"), signV4Algorithm)
|
v4Auth := strings.TrimPrefix(r.Header.Get("Authorization"), signV4Algorithm)
|
||||||
|
@ -46,7 +46,7 @@ func skipContentSha256Cksum(r *http.Request) bool {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if isRequestPresignedSignatureV4(r) {
|
if isRequestPresignedSignatureV4(r) {
|
||||||
v, ok = r.URL.Query()[xhttp.AmzContentSha256]
|
v, ok = r.Form[xhttp.AmzContentSha256]
|
||||||
if !ok {
|
if !ok {
|
||||||
v, ok = r.Header[xhttp.AmzContentSha256]
|
v, ok = r.Header[xhttp.AmzContentSha256]
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ func getContentSha256Cksum(r *http.Request, stype serviceType) string {
|
|||||||
// X-Amz-Content-Sha256, if not set in presigned requests, checksum
|
// X-Amz-Content-Sha256, if not set in presigned requests, checksum
|
||||||
// will default to 'UNSIGNED-PAYLOAD'.
|
// will default to 'UNSIGNED-PAYLOAD'.
|
||||||
defaultSha256Cksum = unsignedPayload
|
defaultSha256Cksum = unsignedPayload
|
||||||
v, ok = r.URL.Query()[xhttp.AmzContentSha256]
|
v, ok = r.Form[xhttp.AmzContentSha256]
|
||||||
if !ok {
|
if !ok {
|
||||||
v, ok = r.Header[xhttp.AmzContentSha256]
|
v, ok = r.Header[xhttp.AmzContentSha256]
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ func sumHMAC(key []byte, data []byte) []byte {
|
|||||||
// extractSignedHeaders extract signed headers from Authorization header
|
// extractSignedHeaders extract signed headers from Authorization header
|
||||||
func extractSignedHeaders(signedHeaders []string, r *http.Request) (http.Header, APIErrorCode) {
|
func extractSignedHeaders(signedHeaders []string, r *http.Request) (http.Header, APIErrorCode) {
|
||||||
reqHeaders := r.Header
|
reqHeaders := r.Header
|
||||||
reqQueries := r.URL.Query()
|
reqQueries := r.Form
|
||||||
// find whether "host" is part of list of signed headers.
|
// find whether "host" is part of list of signed headers.
|
||||||
// if not return ErrUnsignedHeaders. "host" is mandatory.
|
// if not return ErrUnsignedHeaders. "host" is mandatory.
|
||||||
if !contains(signedHeaders, "host") {
|
if !contains(signedHeaders, "host") {
|
||||||
|
@ -89,6 +89,7 @@ func TestSkipContentSha256Cksum(t *testing.T) {
|
|||||||
inputReq.Header.Set(testCase.inputHeaderKey, testCase.inputHeaderValue)
|
inputReq.Header.Set(testCase.inputHeaderKey, testCase.inputHeaderValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inputReq.ParseForm()
|
||||||
|
|
||||||
actualResult := skipContentSha256Cksum(inputReq)
|
actualResult := skipContentSha256Cksum(inputReq)
|
||||||
if testCase.expectedResult != actualResult {
|
if testCase.expectedResult != actualResult {
|
||||||
@ -163,6 +164,7 @@ func TestExtractSignedHeaders(t *testing.T) {
|
|||||||
// set headers value through Get parameter
|
// set headers value through Get parameter
|
||||||
inputQuery.Add("x-amz-server-side-encryption", xhttp.AmzEncryptionAES)
|
inputQuery.Add("x-amz-server-side-encryption", xhttp.AmzEncryptionAES)
|
||||||
r.URL.RawQuery = inputQuery.Encode()
|
r.URL.RawQuery = inputQuery.Encode()
|
||||||
|
r.ParseForm()
|
||||||
_, errCode = extractSignedHeaders(signedHeaders, r)
|
_, errCode = extractSignedHeaders(signedHeaders, r)
|
||||||
if errCode != ErrNone {
|
if errCode != ErrNone {
|
||||||
t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrNone, errCode)
|
t.Fatalf("Expected the APIErrorCode to be %d, but got %d", ErrNone, errCode)
|
||||||
@ -267,6 +269,7 @@ func TestGetContentSha256Cksum(t *testing.T) {
|
|||||||
if testCase.h != "" {
|
if testCase.h != "" {
|
||||||
r.Header.Set("x-amz-content-sha256", testCase.h)
|
r.Header.Set("x-amz-content-sha256", testCase.h)
|
||||||
}
|
}
|
||||||
|
r.ParseForm()
|
||||||
got := getContentSha256Cksum(r, serviceS3)
|
got := getContentSha256Cksum(r, serviceS3)
|
||||||
if got != testCase.expected {
|
if got != testCase.expected {
|
||||||
t.Errorf("Test %d: got:%s expected:%s", i+1, got, testCase.expected)
|
t.Errorf("Test %d: got:%s expected:%s", i+1, got, testCase.expected)
|
||||||
|
@ -209,7 +209,7 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
|
|||||||
req := *r
|
req := *r
|
||||||
|
|
||||||
// Parse request query string.
|
// Parse request query string.
|
||||||
pSignValues, err := parsePreSignV4(req.URL.Query(), region, stype)
|
pSignValues, err := parsePreSignV4(req.Form, region, stype)
|
||||||
if err != ErrNone {
|
if err != ErrNone {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -241,12 +241,12 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
|
|||||||
|
|
||||||
// Construct new query.
|
// Construct new query.
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
clntHashedPayload := req.URL.Query().Get(xhttp.AmzContentSha256)
|
clntHashedPayload := req.Form.Get(xhttp.AmzContentSha256)
|
||||||
if clntHashedPayload != "" {
|
if clntHashedPayload != "" {
|
||||||
query.Set(xhttp.AmzContentSha256, hashedPayload)
|
query.Set(xhttp.AmzContentSha256, hashedPayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
token := req.URL.Query().Get(xhttp.AmzSecurityToken)
|
token := req.Form.Get(xhttp.AmzSecurityToken)
|
||||||
if token != "" {
|
if token != "" {
|
||||||
query.Set(xhttp.AmzSecurityToken, cred.SessionToken)
|
query.Set(xhttp.AmzSecurityToken, cred.SessionToken)
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Add missing query parameters if any provided in the request URL
|
// Add missing query parameters if any provided in the request URL
|
||||||
for k, v := range req.URL.Query() {
|
for k, v := range req.Form {
|
||||||
if !defaultSigParams.Contains(k) {
|
if !defaultSigParams.Contains(k) {
|
||||||
query[k] = v
|
query[k] = v
|
||||||
}
|
}
|
||||||
@ -281,19 +281,19 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
|
|||||||
encodedQuery := query.Encode()
|
encodedQuery := query.Encode()
|
||||||
|
|
||||||
// Verify if date query is same.
|
// Verify if date query is same.
|
||||||
if req.URL.Query().Get(xhttp.AmzDate) != query.Get(xhttp.AmzDate) {
|
if req.Form.Get(xhttp.AmzDate) != query.Get(xhttp.AmzDate) {
|
||||||
return ErrSignatureDoesNotMatch
|
return ErrSignatureDoesNotMatch
|
||||||
}
|
}
|
||||||
// Verify if expires query is same.
|
// Verify if expires query is same.
|
||||||
if req.URL.Query().Get(xhttp.AmzExpires) != query.Get(xhttp.AmzExpires) {
|
if req.Form.Get(xhttp.AmzExpires) != query.Get(xhttp.AmzExpires) {
|
||||||
return ErrSignatureDoesNotMatch
|
return ErrSignatureDoesNotMatch
|
||||||
}
|
}
|
||||||
// Verify if signed headers query is same.
|
// Verify if signed headers query is same.
|
||||||
if req.URL.Query().Get(xhttp.AmzSignedHeaders) != query.Get(xhttp.AmzSignedHeaders) {
|
if req.Form.Get(xhttp.AmzSignedHeaders) != query.Get(xhttp.AmzSignedHeaders) {
|
||||||
return ErrSignatureDoesNotMatch
|
return ErrSignatureDoesNotMatch
|
||||||
}
|
}
|
||||||
// Verify if credential query is same.
|
// Verify if credential query is same.
|
||||||
if req.URL.Query().Get(xhttp.AmzCredential) != query.Get(xhttp.AmzCredential) {
|
if req.Form.Get(xhttp.AmzCredential) != query.Get(xhttp.AmzCredential) {
|
||||||
return ErrSignatureDoesNotMatch
|
return ErrSignatureDoesNotMatch
|
||||||
}
|
}
|
||||||
// Verify if sha256 payload query is same.
|
// Verify if sha256 payload query is same.
|
||||||
@ -321,7 +321,7 @@ func doesPresignedSignatureMatch(hashedPayload string, r *http.Request, region s
|
|||||||
newSignature := getSignature(presignedSigningKey, presignedStringToSign)
|
newSignature := getSignature(presignedSigningKey, presignedStringToSign)
|
||||||
|
|
||||||
// Verify signature.
|
// Verify signature.
|
||||||
if !compareSignatureV4(req.URL.Query().Get(xhttp.AmzSignature), newSignature) {
|
if !compareSignatureV4(req.Form.Get(xhttp.AmzSignature), newSignature) {
|
||||||
return ErrSignatureDoesNotMatch
|
return ErrSignatureDoesNotMatch
|
||||||
}
|
}
|
||||||
return ErrNone
|
return ErrNone
|
||||||
@ -369,7 +369,7 @@ func doesSignatureMatch(hashedPayload string, r *http.Request, region string, st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query string.
|
// Query string.
|
||||||
queryStr := req.URL.Query().Encode()
|
queryStr := req.Form.Encode()
|
||||||
|
|
||||||
// Get canonical request.
|
// Get canonical request.
|
||||||
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, queryStr, req.URL.Path, req.Method)
|
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, queryStr, req.URL.Path, req.Method)
|
||||||
|
@ -293,6 +293,9 @@ func TestDoesPresignedSignatureMatch(t *testing.T) {
|
|||||||
req.Header.Set(key, value)
|
req.Header.Set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse form.
|
||||||
|
req.ParseForm()
|
||||||
|
|
||||||
// Check if it matches!
|
// Check if it matches!
|
||||||
err := doesPresignedSignatureMatch(payloadSHA256, req, testCase.region, serviceS3)
|
err := doesPresignedSignatureMatch(payloadSHA256, req, testCase.region, serviceS3)
|
||||||
if err != testCase.expected {
|
if err != testCase.expected {
|
||||||
|
@ -119,7 +119,7 @@ func (s *storageRESTServer) IsValid(w http.ResponseWriter, r *http.Request) bool
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
diskID := r.URL.Query().Get(storageRESTDiskID)
|
diskID := r.Form.Get(storageRESTDiskID)
|
||||||
if diskID == "" {
|
if diskID == "" {
|
||||||
// Request sent empty disk-id, we allow the request
|
// Request sent empty disk-id, we allow the request
|
||||||
// as the peer might be coming up and trying to read format.json
|
// as the peer might be coming up and trying to read format.json
|
||||||
@ -282,7 +282,7 @@ func (s *storageRESTServer) DeleteVolHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
}
|
}
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
volume := vars[storageRESTVolume]
|
volume := vars[storageRESTVolume]
|
||||||
forceDelete := r.URL.Query().Get(storageRESTForceDelete) == "true"
|
forceDelete := r.Form.Get(storageRESTForceDelete) == "true"
|
||||||
err := s.storage.DeleteVol(r.Context(), volume, forceDelete)
|
err := s.storage.DeleteVol(r.Context(), volume, forceDelete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.writeErrorResponse(w, err)
|
s.writeErrorResponse(w, err)
|
||||||
@ -641,10 +641,8 @@ func (s *storageRESTServer) DeleteVersionsHandler(w http.ResponseWriter, r *http
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := r.URL.Query()
|
volume := r.Form.Get(storageRESTVolume)
|
||||||
volume := vars.Get(storageRESTVolume)
|
totalVersions, err := strconv.Atoi(r.Form.Get(storageRESTTotalVersions))
|
||||||
|
|
||||||
totalVersions, err := strconv.Atoi(vars.Get(storageRESTTotalVersions))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.writeErrorResponse(w, err)
|
s.writeErrorResponse(w, err)
|
||||||
return
|
return
|
||||||
|
@ -117,7 +117,7 @@ func calculateSeedSignature(r *http.Request) (cred auth.Credentials, signature s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query string.
|
// Query string.
|
||||||
queryStr := req.URL.Query().Encode()
|
queryStr := req.Form.Encode()
|
||||||
|
|
||||||
// Get canonical request.
|
// Get canonical request.
|
||||||
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, payload, queryStr, req.URL.Path, req.Method)
|
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, payload, queryStr, req.URL.Path, req.Method)
|
||||||
|
@ -95,14 +95,14 @@ func registerSTSRouter(router *mux.Router) {
|
|||||||
stsRouter.Methods(http.MethodPost).MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
|
stsRouter.Methods(http.MethodPost).MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
|
||||||
ctypeOk := wildcard.MatchSimple("application/x-www-form-urlencoded*", r.Header.Get(xhttp.ContentType))
|
ctypeOk := wildcard.MatchSimple("application/x-www-form-urlencoded*", r.Header.Get(xhttp.ContentType))
|
||||||
authOk := wildcard.MatchSimple(signV4Algorithm+"*", r.Header.Get(xhttp.Authorization))
|
authOk := wildcard.MatchSimple(signV4Algorithm+"*", r.Header.Get(xhttp.Authorization))
|
||||||
noQueries := len(r.URL.Query()) == 0
|
noQueries := len(r.URL.RawQuery) == 0
|
||||||
return ctypeOk && authOk && noQueries
|
return ctypeOk && authOk && noQueries
|
||||||
}).HandlerFunc(httpTraceAll(sts.AssumeRole))
|
}).HandlerFunc(httpTraceAll(sts.AssumeRole))
|
||||||
|
|
||||||
// Assume roles with JWT handler, handles both ClientGrants and WebIdentity.
|
// Assume roles with JWT handler, handles both ClientGrants and WebIdentity.
|
||||||
stsRouter.Methods(http.MethodPost).MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
|
stsRouter.Methods(http.MethodPost).MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) bool {
|
||||||
ctypeOk := wildcard.MatchSimple("application/x-www-form-urlencoded*", r.Header.Get(xhttp.ContentType))
|
ctypeOk := wildcard.MatchSimple("application/x-www-form-urlencoded*", r.Header.Get(xhttp.ContentType))
|
||||||
noQueries := len(r.URL.Query()) == 0
|
noQueries := len(r.URL.RawQuery) == 0
|
||||||
return ctypeOk && noQueries
|
return ctypeOk && noQueries
|
||||||
}).HandlerFunc(httpTraceAll(sts.AssumeRoleWithSSO))
|
}).HandlerFunc(httpTraceAll(sts.AssumeRoleWithSSO))
|
||||||
|
|
||||||
@ -155,6 +155,18 @@ func checkAssumeRoleAuth(ctx context.Context, r *http.Request) (user auth.Creden
|
|||||||
return user, true, ErrSTSNone
|
return user, true, ErrSTSNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseForm(r *http.Request) error {
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for k, v := range r.PostForm {
|
||||||
|
if _, ok := r.Form[k]; !ok {
|
||||||
|
r.Form[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AssumeRole - implementation of AWS STS API AssumeRole to get temporary
|
// AssumeRole - implementation of AWS STS API AssumeRole to get temporary
|
||||||
// credentials for regular users on Minio.
|
// credentials for regular users on Minio.
|
||||||
// https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
|
// https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
|
||||||
@ -167,7 +179,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.ParseForm(); err != nil {
|
if err := parseForm(r); err != nil {
|
||||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -275,7 +287,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
|
|||||||
ctx := newContext(r, w, "AssumeRoleSSOCommon")
|
ctx := newContext(r, w, "AssumeRoleSSOCommon")
|
||||||
|
|
||||||
// Parse the incoming form data.
|
// Parse the incoming form data.
|
||||||
if err := r.ParseForm(); err != nil {
|
if err := parseForm(r); err != nil {
|
||||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -514,7 +526,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
|||||||
defer logger.AuditLog(ctx, w, r, nil, stsLDAPPassword)
|
defer logger.AuditLog(ctx, w, r, nil, stsLDAPPassword)
|
||||||
|
|
||||||
// Parse the incoming form data.
|
// Parse the incoming form data.
|
||||||
if err := r.ParseForm(); err != nil {
|
if err := parseForm(r); err != nil {
|
||||||
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -1648,12 +1649,8 @@ func ExecObjectLayerAPIAnonTest(t *testing.T, obj ObjectLayer, testName, bucketN
|
|||||||
t.Fatal(failTestStr(unknownSignTestStr, "error response failed to parse error XML"))
|
t.Fatal(failTestStr(unknownSignTestStr, "error response failed to parse error XML"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualError.BucketName != bucketName {
|
if path.Clean(actualError.Resource) != pathJoin(SlashSeparator, bucketName, SlashSeparator, objectName) {
|
||||||
t.Fatal(failTestStr(unknownSignTestStr, "error response bucket name differs from expected value"))
|
t.Fatal(failTestStr(unknownSignTestStr, "error response resource differs from expected value"))
|
||||||
}
|
|
||||||
|
|
||||||
if actualError.Key != objectName {
|
|
||||||
t.Fatal(failTestStr(unknownSignTestStr, "error response object name differs from expected value"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2035,13 +2032,15 @@ func registerAPIFunctions(muxRouter *mux.Router, objLayer ObjectLayer, apiFuncti
|
|||||||
func initTestAPIEndPoints(objLayer ObjectLayer, apiFunctions []string) http.Handler {
|
func initTestAPIEndPoints(objLayer ObjectLayer, apiFunctions []string) http.Handler {
|
||||||
// initialize a new mux router.
|
// initialize a new mux router.
|
||||||
// goriilla/mux is the library used to register all the routes and handle them.
|
// goriilla/mux is the library used to register all the routes and handle them.
|
||||||
muxRouter := mux.NewRouter().SkipClean(true)
|
muxRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
||||||
if len(apiFunctions) > 0 {
|
if len(apiFunctions) > 0 {
|
||||||
// Iterate the list of API functions requested for and register them in mux HTTP handler.
|
// Iterate the list of API functions requested for and register them in mux HTTP handler.
|
||||||
registerAPIFunctions(muxRouter, objLayer, apiFunctions...)
|
registerAPIFunctions(muxRouter, objLayer, apiFunctions...)
|
||||||
|
muxRouter.Use(globalHandlers...)
|
||||||
return muxRouter
|
return muxRouter
|
||||||
}
|
}
|
||||||
registerAPIRouter(muxRouter)
|
registerAPIRouter(muxRouter)
|
||||||
|
muxRouter.Use(globalHandlers...)
|
||||||
return muxRouter
|
return muxRouter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
70
cmd/url_test.go
Normal file
70
cmd/url_test.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of MinIO Object Storage stack
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkURLQueryForm(b *testing.B) {
|
||||||
|
req, err := http.NewRequest(http.MethodGet, "http://localhost:9000/bucket/name?uploadId=upload&partNumber=1", nil)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// benchmark utility which helps obtain number of allocations and bytes allocated per ops.
|
||||||
|
b.ReportAllocs()
|
||||||
|
// the actual benchmark for PutObject starts here. Reset the benchmark timer.
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
req.Form.Get("uploadId")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Benchmark ends here. Stop timer.
|
||||||
|
b.StopTimer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BenchmarkURLQuery - benchmark URL memory allocations
|
||||||
|
func BenchmarkURLQuery(b *testing.B) {
|
||||||
|
req, err := http.NewRequest(http.MethodGet, "http://localhost:9000/bucket/name?uploadId=upload&partNumber=1", nil)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// benchmark utility which helps obtain number of allocations and bytes allocated per ops.
|
||||||
|
b.ReportAllocs()
|
||||||
|
// the actual benchmark for PutObject starts here. Reset the benchmark timer.
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
req.URL.Query().Get("uploadId")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Benchmark ends here. Stop timer.
|
||||||
|
b.StopTimer()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user