mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
Redirect browser requests returning AccessDenied (#6848)
Anonymous requests from S3 resources returning AccessDenied should be auto redirected to browser for login.
This commit is contained in:
parent
dd092f6c2b
commit
dba61867e8
@ -64,21 +64,21 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.
|
|||||||
|
|
||||||
objAPI := api.ObjectAPI()
|
objAPI := api.ObjectAPI()
|
||||||
if objAPI == nil {
|
if objAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow getBucketACL if policy action is set, since this is a dummy call
|
// Allow getBucketACL if policy action is set, since this is a dummy call
|
||||||
// we are simply re-purposing the bucketPolicyAction.
|
// we are simply re-purposing the bucketPolicyAction.
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before proceeding validate if bucket exists.
|
// Before proceeding validate if bucket exists.
|
||||||
_, err := objAPI.GetBucketInfo(ctx, bucket)
|
_, err := objAPI.GetBucketInfo(ctx, bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ func (api objectAPIHandlers) GetBucketACLHandler(w http.ResponseWriter, r *http.
|
|||||||
Permission: "FULL_CONTROL",
|
Permission: "FULL_CONTROL",
|
||||||
})
|
})
|
||||||
if err := xml.NewEncoder(w).Encode(acl); err != nil {
|
if err := xml.NewEncoder(w).Encode(acl); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,21 +114,21 @@ func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http.
|
|||||||
|
|
||||||
objAPI := api.ObjectAPI()
|
objAPI := api.ObjectAPI()
|
||||||
if objAPI == nil {
|
if objAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow getObjectACL if policy action is set, since this is a dummy call
|
// Allow getObjectACL if policy action is set, since this is a dummy call
|
||||||
// we are simply re-purposing the bucketPolicyAction.
|
// we are simply re-purposing the bucketPolicyAction.
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before proceeding validate if object exists.
|
// Before proceeding validate if object exists.
|
||||||
_, err := objAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{})
|
_, err := objAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ func (api objectAPIHandlers) GetObjectACLHandler(w http.ResponseWriter, r *http.
|
|||||||
Permission: "FULL_CONTROL",
|
Permission: "FULL_CONTROL",
|
||||||
})
|
})
|
||||||
if err := xml.NewEncoder(w).Encode(acl); err != nil {
|
if err := xml.NewEncoder(w).Encode(acl); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,7 +578,7 @@ func (a adminAPIHandlers) HealHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
StartTime: nh.startTime,
|
StartTime: nh.startTime,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAdminAPIErrCode(ctx, err), r.URL)
|
writeErrorResponseJSON(w, toAdminAPIErrCode(ctx, err), r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Client token not specified but a heal sequence exists on a path,
|
// Client token not specified but a heal sequence exists on a path,
|
||||||
@ -859,7 +859,7 @@ func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
// Custom IAM policies not allowed for admin user.
|
// Custom IAM policies not allowed for admin user.
|
||||||
if accessKey == globalServerConfig.GetCredential().AccessKey {
|
if accessKey == globalServerConfig.GetCredential().AccessKey {
|
||||||
writeErrorResponse(w, ErrInvalidRequest, r.URL)
|
writeErrorResponseJSON(w, ErrInvalidRequest, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,7 +898,7 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// Custom IAM policies not allowed for admin user.
|
// Custom IAM policies not allowed for admin user.
|
||||||
if accessKey == globalServerConfig.GetCredential().AccessKey {
|
if accessKey == globalServerConfig.GetCredential().AccessKey {
|
||||||
writeErrorResponse(w, ErrInvalidRequest, r.URL)
|
writeErrorResponseJSON(w, ErrInvalidRequest, r.URL)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,13 +568,20 @@ func writeSuccessResponseHeadersOnly(w http.ResponseWriter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writeErrorRespone writes error headers
|
// writeErrorRespone writes error headers
|
||||||
func writeErrorResponse(w http.ResponseWriter, errorCode APIErrorCode, reqURL *url.URL) {
|
func writeErrorResponse(w http.ResponseWriter, errorCode APIErrorCode, reqURL *url.URL, browser bool) {
|
||||||
switch errorCode {
|
switch errorCode {
|
||||||
case ErrSlowDown, ErrServerNotInitialized, ErrReadQuorum, ErrWriteQuorum:
|
case ErrSlowDown, ErrServerNotInitialized, ErrReadQuorum, ErrWriteQuorum:
|
||||||
// Set retry-after header to indicate user-agents to retry request after 120secs.
|
// Set retry-after header to indicate user-agents to retry request after 120secs.
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
||||||
w.Header().Set("Retry-After", "120")
|
w.Header().Set("Retry-After", "120")
|
||||||
|
case ErrAccessDenied:
|
||||||
|
if browser {
|
||||||
|
w.Header().Set("Location", minioReservedBucketPath+reqURL.Path)
|
||||||
|
w.WriteHeader(http.StatusTemporaryRedirect)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apiError := getAPIError(errorCode)
|
apiError := getAPIError(errorCode)
|
||||||
// Generate error response.
|
// Generate error response.
|
||||||
errorResponse := getAPIErrorResponse(apiError, reqURL.Path, w.Header().Get(responseRequestIDKey))
|
errorResponse := getAPIErrorResponse(apiError, reqURL.Path, w.Header().Get(responseRequestIDKey))
|
||||||
|
@ -419,7 +419,7 @@ func (a authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
a.handler.ServeHTTP(w, r)
|
a.handler.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeErrorResponse(w, ErrSignatureVersionNotSupported, r.URL)
|
writeErrorResponse(w, ErrSignatureVersionNotSupported, r.URL, guessIsBrowserReq(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
// isPutAllowed - check if PUT operation is allowed on the resource, this
|
// isPutAllowed - check if PUT operation is allowed on the resource, this
|
||||||
|
@ -66,12 +66,12 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,14 +81,14 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
|
|||||||
prefix, token, startAfter, delimiter, fetchOwner, maxKeys, _, errCode := getListObjectsV2Args(urlValues)
|
prefix, token, startAfter, delimiter, fetchOwner, maxKeys, _, errCode := getListObjectsV2Args(urlValues)
|
||||||
|
|
||||||
if errCode != ErrNone {
|
if errCode != ErrNone {
|
||||||
writeErrorResponse(w, errCode, r.URL)
|
writeErrorResponse(w, errCode, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the query params before beginning to serve the request.
|
// Validate the query params before beginning to serve the request.
|
||||||
// fetch-owner is not validated since it is a boolean
|
// fetch-owner is not validated since it is a boolean
|
||||||
if s3Error := validateListObjectsArgs(prefix, token, delimiter, maxKeys); s3Error != ErrNone {
|
if s3Error := validateListObjectsArgs(prefix, token, delimiter, maxKeys); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
listObjectsV2 := objectAPI.ListObjectsV2
|
listObjectsV2 := objectAPI.ListObjectsV2
|
||||||
@ -100,7 +100,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
|
|||||||
// marshaled into S3 compatible XML header.
|
// marshaled into S3 compatible XML header.
|
||||||
listObjectsV2Info, err := listObjectsV2(ctx, bucket, prefix, token, delimiter, maxKeys, fetchOwner, startAfter)
|
listObjectsV2Info, err := listObjectsV2(ctx, bucket, prefix, token, delimiter, maxKeys, fetchOwner, startAfter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
|
|||||||
// Read the decompressed size from the meta.json.
|
// Read the decompressed size from the meta.json.
|
||||||
actualSize = listObjectsV2Info.Objects[i].GetActualSize()
|
actualSize = listObjectsV2Info.Objects[i].GetActualSize()
|
||||||
if actualSize < 0 {
|
if actualSize < 0 {
|
||||||
writeErrorResponse(w, ErrInvalidDecompressedSize, r.URL)
|
writeErrorResponse(w, ErrInvalidDecompressedSize, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Set the info.Size to the actualSize.
|
// Set the info.Size to the actualSize.
|
||||||
@ -119,7 +119,7 @@ func (api objectAPIHandlers) ListObjectsV2Handler(w http.ResponseWriter, r *http
|
|||||||
listObjectsV2Info.Objects[i].ETag = getDecryptedETag(r.Header, listObjectsV2Info.Objects[i], false)
|
listObjectsV2Info.Objects[i].ETag = getDecryptedETag(r.Header, listObjectsV2Info.Objects[i], false)
|
||||||
listObjectsV2Info.Objects[i].Size, err = listObjectsV2Info.Objects[i].DecryptedSize()
|
listObjectsV2Info.Objects[i].Size, err = listObjectsV2Info.Objects[i].DecryptedSize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,30 +148,30 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract all the litsObjectsV1 query params to their native values.
|
// Extract all the litsObjectsV1 query params to their native values.
|
||||||
prefix, marker, delimiter, maxKeys, _, s3Error := getListObjectsV1Args(r.URL.Query())
|
prefix, marker, delimiter, maxKeys, _, s3Error := getListObjectsV1Args(r.URL.Query())
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the maxKeys lowerbound. When maxKeys > 1000, S3 returns 1000 but
|
// Validate the maxKeys lowerbound. When maxKeys > 1000, S3 returns 1000 but
|
||||||
// does not throw an error.
|
// does not throw an error.
|
||||||
if maxKeys < 0 {
|
if maxKeys < 0 {
|
||||||
writeErrorResponse(w, ErrInvalidMaxKeys, r.URL)
|
writeErrorResponse(w, ErrInvalidMaxKeys, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
} // Validate all the query params before beginning to serve the request.
|
} // Validate all the query params before beginning to serve the request.
|
||||||
if s3Error := validateListObjectsArgs(prefix, marker, delimiter, maxKeys); s3Error != ErrNone {
|
if s3Error := validateListObjectsArgs(prefix, marker, delimiter, maxKeys); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
listObjects := objectAPI.ListObjects
|
listObjects := objectAPI.ListObjects
|
||||||
@ -183,7 +183,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
|
|||||||
// marshaled into S3 compatible XML header.
|
// marshaled into S3 compatible XML header.
|
||||||
listObjectsInfo, err := listObjects(ctx, bucket, prefix, marker, delimiter, maxKeys)
|
listObjectsInfo, err := listObjects(ctx, bucket, prefix, marker, delimiter, maxKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
|
|||||||
// Read the decompressed size from the meta.json.
|
// Read the decompressed size from the meta.json.
|
||||||
actualSize = listObjectsInfo.Objects[i].GetActualSize()
|
actualSize = listObjectsInfo.Objects[i].GetActualSize()
|
||||||
if actualSize < 0 {
|
if actualSize < 0 {
|
||||||
writeErrorResponse(w, ErrInvalidDecompressedSize, r.URL)
|
writeErrorResponse(w, ErrInvalidDecompressedSize, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Set the info.Size to the actualSize.
|
// Set the info.Size to the actualSize.
|
||||||
@ -202,7 +202,7 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
|
|||||||
listObjectsInfo.Objects[i].ETag = getDecryptedETag(r.Header, listObjectsInfo.Objects[i], false)
|
listObjectsInfo.Objects[i].ETag = getDecryptedETag(r.Header, listObjectsInfo.Objects[i], false)
|
||||||
listObjectsInfo.Objects[i].Size, err = listObjectsInfo.Objects[i].DecryptedSize()
|
listObjectsInfo.Objects[i].Size, err = listObjectsInfo.Objects[i].DecryptedSize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,12 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketLocationAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketLocationAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ func (api objectAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *
|
|||||||
getBucketInfo = api.CacheAPI().GetBucketInfo
|
getBucketInfo = api.CacheAPI().GetBucketInfo
|
||||||
}
|
}
|
||||||
if _, err := getBucketInfo(ctx, bucket); err != nil {
|
if _, err := getBucketInfo(ctx, bucket); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,35 +146,35 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter,
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketMultipartUploadsAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.ListBucketMultipartUploadsAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix, keyMarker, uploadIDMarker, delimiter, maxUploads, _, s3Error := getBucketMultipartResources(r.URL.Query())
|
prefix, keyMarker, uploadIDMarker, delimiter, maxUploads, _, s3Error := getBucketMultipartResources(r.URL.Query())
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if maxUploads < 0 {
|
if maxUploads < 0 {
|
||||||
writeErrorResponse(w, ErrInvalidMaxUploads, r.URL)
|
writeErrorResponse(w, ErrInvalidMaxUploads, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if keyMarker != "" {
|
if keyMarker != "" {
|
||||||
// Marker not common with prefix is not implemented.
|
// Marker not common with prefix is not implemented.
|
||||||
if !hasPrefix(keyMarker, prefix) {
|
if !hasPrefix(keyMarker, prefix) {
|
||||||
writeErrorResponse(w, ErrNotImplemented, r.URL)
|
writeErrorResponse(w, ErrNotImplemented, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listMultipartsInfo, err := objectAPI.ListMultipartUploads(ctx, bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads)
|
listMultipartsInfo, err := objectAPI.ListMultipartUploads(ctx, bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploads)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// generate response
|
// generate response
|
||||||
@ -196,7 +196,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
listBuckets := objectAPI.ListBuckets
|
listBuckets := objectAPI.ListBuckets
|
||||||
@ -206,7 +206,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.ListAllMyBucketsAction, "", ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.ListAllMyBucketsAction, "", ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// If etcd, dns federation configured list buckets from etcd.
|
// If etcd, dns federation configured list buckets from etcd.
|
||||||
@ -214,7 +214,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
|||||||
if globalDNSConfig != nil {
|
if globalDNSConfig != nil {
|
||||||
dnsBuckets, err := globalDNSConfig.List()
|
dnsBuckets, err := globalDNSConfig.List()
|
||||||
if err != nil && err != dns.ErrNoEntriesFound {
|
if err != nil && err != dns.ErrNoEntriesFound {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bucketSet := set.NewStringSet()
|
bucketSet := set.NewStringSet()
|
||||||
@ -233,7 +233,7 @@ func (api objectAPIHandlers) ListBucketsHandler(w http.ResponseWriter, r *http.R
|
|||||||
var err error
|
var err error
|
||||||
bucketsInfo, err = listBuckets(ctx)
|
bucketsInfo, err = listBuckets(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
|||||||
// In the event access is denied, a 200 response should still be returned
|
// In the event access is denied, a 200 response should still be returned
|
||||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
|
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
|
||||||
if s3Error != ErrAccessDenied {
|
if s3Error != ErrAccessDenied {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,14 +274,14 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
|||||||
// Content-Length is required and should be non-zero
|
// Content-Length is required and should be non-zero
|
||||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
|
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
|
||||||
if r.ContentLength <= 0 {
|
if r.ContentLength <= 0 {
|
||||||
writeErrorResponse(w, ErrMissingContentLength, r.URL)
|
writeErrorResponse(w, ErrMissingContentLength, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content-Md5 is requied should be set
|
// Content-Md5 is requied should be set
|
||||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
|
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
|
||||||
if _, ok := r.Header["Content-Md5"]; !ok {
|
if _, ok := r.Header["Content-Md5"]; !ok {
|
||||||
writeErrorResponse(w, ErrMissingContentMD5, r.URL)
|
writeErrorResponse(w, ErrMissingContentMD5, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +297,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
|||||||
// Read incoming body XML bytes.
|
// Read incoming body XML bytes.
|
||||||
if _, err := io.ReadFull(r.Body, deleteXMLBytes); err != nil {
|
if _, err := io.ReadFull(r.Body, deleteXMLBytes); err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, ErrInternalError, r.URL)
|
writeErrorResponse(w, ErrInternalError, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
|||||||
deleteObjects := &DeleteObjectsRequest{}
|
deleteObjects := &DeleteObjectsRequest{}
|
||||||
if err := xml.Unmarshal(deleteXMLBytes, deleteObjects); err != nil {
|
if err := xml.Unmarshal(deleteXMLBytes, deleteObjects); err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, ErrMalformedXML, r.URL)
|
writeErrorResponse(w, ErrMalformedXML, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter,
|
|||||||
if globalWORMEnabled {
|
if globalWORMEnabled {
|
||||||
// Not required to check whether given objects exist or not, because
|
// Not required to check whether given objects exist or not, because
|
||||||
// DeleteMultipleObject is always successful irrespective of object existence.
|
// DeleteMultipleObject is always successful irrespective of object existence.
|
||||||
writeErrorResponse(w, ErrMethodNotAllowed, r.URL)
|
writeErrorResponse(w, ErrMethodNotAllowed, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +401,7 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,21 +409,21 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
|
|||||||
bucket := vars["bucket"]
|
bucket := vars["bucket"]
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.CreateBucketAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.CreateBucketAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse incoming location constraint.
|
// Parse incoming location constraint.
|
||||||
location, s3Error := parseLocationConstraint(r)
|
location, s3Error := parseLocationConstraint(r)
|
||||||
if s3Error != ErrNone {
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate if location sent by the client is valid, reject
|
// Validate if location sent by the client is valid, reject
|
||||||
// requests which do not follow valid region requirements.
|
// requests which do not follow valid region requirements.
|
||||||
if !isValidLocation(location) {
|
if !isValidLocation(location) {
|
||||||
writeErrorResponse(w, ErrInvalidRegion, r.URL)
|
writeErrorResponse(w, ErrInvalidRegion, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,12 +432,12 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
|
|||||||
if err == dns.ErrNoEntriesFound {
|
if err == dns.ErrNoEntriesFound {
|
||||||
// Proceed to creating a bucket.
|
// Proceed to creating a bucket.
|
||||||
if err = objectAPI.MakeBucketWithLocation(ctx, bucket, location); err != nil {
|
if err = objectAPI.MakeBucketWithLocation(ctx, bucket, location); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = globalDNSConfig.Put(bucket); err != nil {
|
if err = globalDNSConfig.Put(bucket); err != nil {
|
||||||
objectAPI.DeleteBucket(ctx, bucket)
|
objectAPI.DeleteBucket(ctx, bucket)
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,18 +447,18 @@ func (api objectAPIHandlers) PutBucketHandler(w http.ResponseWriter, r *http.Req
|
|||||||
writeSuccessResponseHeadersOnly(w)
|
writeSuccessResponseHeadersOnly(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
writeErrorResponse(w, ErrBucketAlreadyOwnedByYou, r.URL)
|
writeErrorResponse(w, ErrBucketAlreadyOwnedByYou, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Proceed to creating a bucket.
|
// Proceed to creating a bucket.
|
||||||
err := objectAPI.MakeBucketWithLocation(ctx, bucket, location)
|
err := objectAPI.MakeBucketWithLocation(ctx, bucket, location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +479,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,17 +488,17 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
// Require Content-Length to be set in the request
|
// Require Content-Length to be set in the request
|
||||||
size := r.ContentLength
|
size := r.ContentLength
|
||||||
if size < 0 {
|
if size < 0 {
|
||||||
writeErrorResponse(w, ErrMissingContentLength, r.URL)
|
writeErrorResponse(w, ErrMissingContentLength, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resource, err := getResource(r.URL.Path, r.Host, globalDomainName)
|
resource, err := getResource(r.URL.Path, r.Host, globalDomainName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, ErrInvalidRequest, r.URL)
|
writeErrorResponse(w, ErrInvalidRequest, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Make sure that the URL does not contain object name.
|
// Make sure that the URL does not contain object name.
|
||||||
if bucket != filepath.Clean(resource[1:]) {
|
if bucket != filepath.Clean(resource[1:]) {
|
||||||
writeErrorResponse(w, ErrMethodNotAllowed, r.URL)
|
writeErrorResponse(w, ErrMethodNotAllowed, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,7 +507,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
reader, err := r.MultipartReader()
|
reader, err := r.MultipartReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL)
|
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,7 +515,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
form, err := reader.ReadForm(maxFormMemory)
|
form, err := reader.ReadForm(maxFormMemory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL)
|
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,13 +526,13 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
fileBody, fileName, fileSize, formValues, err := extractPostPolicyFormValues(ctx, form)
|
fileBody, fileName, fileSize, formValues, err := extractPostPolicyFormValues(ctx, form)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL)
|
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if file is provided, error out otherwise.
|
// Check if file is provided, error out otherwise.
|
||||||
if fileBody == nil {
|
if fileBody == nil {
|
||||||
writeErrorResponse(w, ErrPOSTFileRequired, r.URL)
|
writeErrorResponse(w, ErrPOSTFileRequired, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,7 +554,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
if successRedirect != "" {
|
if successRedirect != "" {
|
||||||
redirectURL, err = url.Parse(successRedirect)
|
redirectURL, err = url.Parse(successRedirect)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL)
|
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -562,25 +562,25 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
// Verify policy signature.
|
// Verify policy signature.
|
||||||
apiErr := doesPolicySignatureMatch(formValues)
|
apiErr := doesPolicySignatureMatch(formValues)
|
||||||
if apiErr != ErrNone {
|
if apiErr != ErrNone {
|
||||||
writeErrorResponse(w, apiErr, r.URL)
|
writeErrorResponse(w, apiErr, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
policyBytes, err := base64.StdEncoding.DecodeString(formValues.Get("Policy"))
|
policyBytes, err := base64.StdEncoding.DecodeString(formValues.Get("Policy"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL)
|
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
postPolicyForm, err := parsePostPolicyForm(string(policyBytes))
|
postPolicyForm, err := parsePostPolicyForm(string(policyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL)
|
writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure formValues adhere to policy restrictions.
|
// Make sure formValues adhere to policy restrictions.
|
||||||
if apiErr = checkPostPolicy(formValues, postPolicyForm); apiErr != ErrNone {
|
if apiErr = checkPostPolicy(formValues, postPolicyForm); apiErr != ErrNone {
|
||||||
writeErrorResponse(w, apiErr, r.URL)
|
writeErrorResponse(w, apiErr, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,12 +589,12 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
lengthRange := postPolicyForm.Conditions.ContentLengthRange
|
lengthRange := postPolicyForm.Conditions.ContentLengthRange
|
||||||
if lengthRange.Valid {
|
if lengthRange.Valid {
|
||||||
if fileSize < lengthRange.Min {
|
if fileSize < lengthRange.Min {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, errDataTooSmall), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, errDataTooSmall), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileSize > lengthRange.Max || isMaxObjectSize(fileSize) {
|
if fileSize > lengthRange.Max || isMaxObjectSize(fileSize) {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, errDataTooLarge), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, errDataTooLarge), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -603,14 +603,14 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
metadata := make(map[string]string)
|
metadata := make(map[string]string)
|
||||||
err = extractMetadataFromMap(ctx, formValues, metadata)
|
err = extractMetadataFromMap(ctx, formValues, metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, ErrInternalError, r.URL)
|
writeErrorResponse(w, ErrInternalError, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hashReader, err := hash.NewReader(fileBody, fileSize, "", "", fileSize)
|
hashReader, err := hash.NewReader(fileBody, fileSize, "", "", fileSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogIf(ctx, err)
|
logger.LogIf(ctx, err)
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rawReader := hashReader
|
rawReader := hashReader
|
||||||
@ -623,19 +623,19 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
if crypto.SSEC.IsRequested(formValues) {
|
if crypto.SSEC.IsRequested(formValues) {
|
||||||
key, err = ParseSSECustomerHeader(formValues)
|
key, err = ParseSSECustomerHeader(formValues)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader, objectEncryptionKey, err = newEncryptReader(hashReader, key, bucket, object, metadata, crypto.S3.IsRequested(formValues))
|
reader, objectEncryptionKey, err = newEncryptReader(hashReader, key, bucket, object, metadata, crypto.S3.IsRequested(formValues))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
info := ObjectInfo{Size: fileSize}
|
info := ObjectInfo{Size: fileSize}
|
||||||
hashReader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", fileSize) // do not try to verify encrypted content
|
hashReader, err = hash.NewReader(reader, info.EncryptedSize(), "", "", fileSize) // do not try to verify encrypted content
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pReader = NewPutObjReader(rawReader, hashReader, objectEncryptionKey)
|
pReader = NewPutObjReader(rawReader, hashReader, objectEncryptionKey)
|
||||||
@ -644,7 +644,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
|
|||||||
|
|
||||||
objInfo, err := objectAPI.PutObject(ctx, bucket, object, pReader, metadata, ObjectOptions{})
|
objInfo, err := objectAPI.PutObject(ctx, bucket, object, pReader, metadata, ObjectOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,12 +742,12 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.DeleteBucketAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.DeleteBucketAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,7 +757,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.
|
|||||||
}
|
}
|
||||||
// Attempt to delete bucket.
|
// Attempt to delete bucket.
|
||||||
if err := deleteBucket(ctx, bucket); err != nil {
|
if err := deleteBucket(ctx, bucket); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +769,7 @@ func (api objectAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.
|
|||||||
if err := globalDNSConfig.Delete(bucket); err != nil {
|
if err := globalDNSConfig.Delete(bucket); err != nil {
|
||||||
// Deleting DNS entry failed, attempt to create the bucket again.
|
// Deleting DNS entry failed, attempt to create the bucket again.
|
||||||
objectAPI.MakeBucketWithLocation(ctx, bucket, "")
|
objectAPI.MakeBucketWithLocation(ctx, bucket, "")
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,23 +51,23 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
|
|
||||||
objAPI := api.ObjectAPI()
|
objAPI := api.ObjectAPI()
|
||||||
if objAPI == nil {
|
if objAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !objAPI.IsNotificationSupported() {
|
if !objAPI.IsNotificationSupported() {
|
||||||
writeErrorResponse(w, ErrNotImplemented, r.URL)
|
writeErrorResponse(w, ErrNotImplemented, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketNotificationAction, bucketName, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketNotificationAction, bucketName, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := objAPI.GetBucketInfo(ctx, bucketName)
|
_, err := objAPI.GetBucketInfo(ctx, bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// Ignore errNoSuchNotifications to comply with AWS S3.
|
// Ignore errNoSuchNotifications to comply with AWS S3.
|
||||||
if err != errNoSuchNotifications {
|
if err != errNoSuchNotifications {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ func (api objectAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
|
|
||||||
notificationBytes, err := xml.Marshal(nConfig)
|
notificationBytes, err := xml.Marshal(nConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,12 +106,12 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
|
|
||||||
objectAPI := api.ObjectAPI()
|
objectAPI := api.ObjectAPI()
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !objectAPI.IsNotificationSupported() {
|
if !objectAPI.IsNotificationSupported() {
|
||||||
writeErrorResponse(w, ErrNotImplemented, r.URL)
|
writeErrorResponse(w, ErrNotImplemented, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,19 +119,19 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
bucketName := vars["bucket"]
|
bucketName := vars["bucket"]
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketNotificationAction, bucketName, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketNotificationAction, bucketName, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := objectAPI.GetBucketInfo(ctx, bucketName)
|
_, err := objectAPI.GetBucketInfo(ctx, bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutBucketNotification always needs a Content-Length.
|
// PutBucketNotification always needs a Content-Length.
|
||||||
if r.ContentLength <= 0 {
|
if r.ContentLength <= 0 {
|
||||||
writeErrorResponse(w, ErrMissingContentLength, r.URL)
|
writeErrorResponse(w, ErrMissingContentLength, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,12 +143,12 @@ func (api objectAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter,
|
|||||||
apiErr = toAPIErrorCode(ctx, err)
|
apiErr = toAPIErrorCode(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeErrorResponse(w, apiErr, r.URL)
|
writeErrorResponse(w, apiErr, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = saveNotificationConfig(ctx, objectAPI, bucketName, config); err != nil {
|
if err = saveNotificationConfig(ctx, objectAPI, bucketName, config); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,11 +169,11 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
// Validate if bucket exists.
|
// Validate if bucket exists.
|
||||||
objAPI := api.ObjectAPI()
|
objAPI := api.ObjectAPI()
|
||||||
if objAPI == nil {
|
if objAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !objAPI.IsNotificationSupported() {
|
if !objAPI.IsNotificationSupported() {
|
||||||
writeErrorResponse(w, ErrNotImplemented, r.URL)
|
writeErrorResponse(w, ErrNotImplemented, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
bucketName := vars["bucket"]
|
bucketName := vars["bucket"]
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.ListenBucketNotificationAction, bucketName, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.ListenBucketNotificationAction, bucketName, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,11 +189,11 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
|
|
||||||
var prefix string
|
var prefix string
|
||||||
if len(values["prefix"]) > 1 {
|
if len(values["prefix"]) > 1 {
|
||||||
writeErrorResponse(w, ErrFilterNamePrefix, r.URL)
|
writeErrorResponse(w, ErrFilterNamePrefix, r.URL, guessIsBrowserReq(r))
|
||||||
}
|
}
|
||||||
if len(values["prefix"]) == 1 {
|
if len(values["prefix"]) == 1 {
|
||||||
if err := event.ValidateFilterRuleValue(values["prefix"][0]); err != nil {
|
if err := event.ValidateFilterRuleValue(values["prefix"][0]); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,11 +202,11 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
|
|
||||||
var suffix string
|
var suffix string
|
||||||
if len(values["suffix"]) > 1 {
|
if len(values["suffix"]) > 1 {
|
||||||
writeErrorResponse(w, ErrFilterNameSuffix, r.URL)
|
writeErrorResponse(w, ErrFilterNameSuffix, r.URL, guessIsBrowserReq(r))
|
||||||
}
|
}
|
||||||
if len(values["suffix"]) == 1 {
|
if len(values["suffix"]) == 1 {
|
||||||
if err := event.ValidateFilterRuleValue(values["suffix"][0]); err != nil {
|
if err := event.ValidateFilterRuleValue(values["suffix"][0]); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
for _, s := range values["events"] {
|
for _, s := range values["events"] {
|
||||||
eventName, err := event.ParseName(s)
|
eventName, err := event.ParseName(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,19 +227,19 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, err := objAPI.GetBucketInfo(ctx, bucketName); err != nil {
|
if _, err := objAPI.GetBucketInfo(ctx, bucketName); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
host, err := xnet.ParseHost(r.RemoteAddr)
|
host, err := xnet.ParseHost(r.RemoteAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
target, err := target.NewHTTPClientTarget(*host, w)
|
target, err := target.NewHTTPClientTarget(*host, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
|
|
||||||
if err = globalNotificationSys.AddRemoteTarget(bucketName, target, rulesMap); err != nil {
|
if err = globalNotificationSys.AddRemoteTarget(bucketName, target, rulesMap); err != nil {
|
||||||
logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name)
|
logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name)
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer globalNotificationSys.RemoveRemoteTarget(bucketName, target.ID())
|
defer globalNotificationSys.RemoveRemoteTarget(bucketName, target.ID())
|
||||||
@ -255,13 +255,13 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
|
|
||||||
thisAddr, err := xnet.ParseHost(GetLocalPeer(globalEndpoints))
|
thisAddr, err := xnet.ParseHost(GetLocalPeer(globalEndpoints))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = SaveListener(objAPI, bucketName, eventNames, pattern, target.ID(), *thisAddr); err != nil {
|
if err = SaveListener(objAPI, bucketName, eventNames, pattern, target.ID(), *thisAddr); err != nil {
|
||||||
logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name)
|
logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name)
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ func (api objectAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWrit
|
|||||||
|
|
||||||
if err = RemoveListener(objAPI, bucketName, target.ID(), *thisAddr); err != nil {
|
if err = RemoveListener(objAPI, bucketName, target.ID(), *thisAddr); err != nil {
|
||||||
logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name)
|
logger.GetReqInfo(ctx).AppendTags("target", target.ID().Name)
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht
|
|||||||
|
|
||||||
objAPI := api.ObjectAPI()
|
objAPI := api.ObjectAPI()
|
||||||
if objAPI == nil {
|
if objAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,43 +52,43 @@ func (api objectAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *ht
|
|||||||
bucket := vars["bucket"]
|
bucket := vars["bucket"]
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.PutBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if bucket exists.
|
// Check if bucket exists.
|
||||||
if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil {
|
if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error out if Content-Length is missing.
|
// Error out if Content-Length is missing.
|
||||||
// PutBucketPolicy always needs Content-Length.
|
// PutBucketPolicy always needs Content-Length.
|
||||||
if r.ContentLength <= 0 {
|
if r.ContentLength <= 0 {
|
||||||
writeErrorResponse(w, ErrMissingContentLength, r.URL)
|
writeErrorResponse(w, ErrMissingContentLength, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error out if Content-Length is beyond allowed size.
|
// Error out if Content-Length is beyond allowed size.
|
||||||
if r.ContentLength > maxBucketPolicySize {
|
if r.ContentLength > maxBucketPolicySize {
|
||||||
writeErrorResponse(w, ErrEntityTooLarge, r.URL)
|
writeErrorResponse(w, ErrEntityTooLarge, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketPolicy, err := policy.ParseConfig(io.LimitReader(r.Body, r.ContentLength), bucket)
|
bucketPolicy, err := policy.ParseConfig(io.LimitReader(r.Body, r.ContentLength), bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, ErrMalformedPolicy, r.URL)
|
writeErrorResponse(w, ErrMalformedPolicy, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version in policy must not be empty
|
// Version in policy must not be empty
|
||||||
if bucketPolicy.Version == "" {
|
if bucketPolicy.Version == "" {
|
||||||
writeErrorResponse(w, ErrMalformedPolicy, r.URL)
|
writeErrorResponse(w, ErrMalformedPolicy, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = objAPI.SetBucketPolicy(ctx, bucket, bucketPolicy); err != nil {
|
if err = objAPI.SetBucketPolicy(ctx, bucket, bucketPolicy); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r
|
|||||||
|
|
||||||
objAPI := api.ObjectAPI()
|
objAPI := api.ObjectAPI()
|
||||||
if objAPI == nil {
|
if objAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,18 +115,18 @@ func (api objectAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r
|
|||||||
bucket := vars["bucket"]
|
bucket := vars["bucket"]
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.DeleteBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.DeleteBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if bucket exists.
|
// Check if bucket exists.
|
||||||
if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil {
|
if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := objAPI.DeleteBucketPolicy(ctx, bucket); err != nil {
|
if err := objAPI.DeleteBucketPolicy(ctx, bucket); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *ht
|
|||||||
|
|
||||||
objAPI := api.ObjectAPI()
|
objAPI := api.ObjectAPI()
|
||||||
if objAPI == nil {
|
if objAPI == nil {
|
||||||
writeErrorResponse(w, ErrServerNotInitialized, r.URL)
|
writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,26 +153,26 @@ func (api objectAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *ht
|
|||||||
bucket := vars["bucket"]
|
bucket := vars["bucket"]
|
||||||
|
|
||||||
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
if s3Error := checkRequestAuthType(ctx, r, policy.GetBucketPolicyAction, bucket, ""); s3Error != ErrNone {
|
||||||
writeErrorResponse(w, s3Error, r.URL)
|
writeErrorResponse(w, s3Error, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if bucket exists.
|
// Check if bucket exists.
|
||||||
if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil {
|
if _, err := objAPI.GetBucketInfo(ctx, bucket); err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read bucket access policy.
|
// Read bucket access policy.
|
||||||
bucketPolicy, err := objAPI.GetBucketPolicy(ctx, bucket)
|
bucketPolicy, err := objAPI.GetBucketPolicy(ctx, bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
policyData, err := json.Marshal(bucketPolicy)
|
policyData, err := json.Marshal(bucketPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Writes S3 compatible copy part range error.
|
// Writes S3 compatible copy part range error.
|
||||||
func writeCopyPartErr(w http.ResponseWriter, err error, url *url.URL) {
|
func writeCopyPartErr(w http.ResponseWriter, err error, url *url.URL, browser bool) {
|
||||||
switch err {
|
switch err {
|
||||||
case errInvalidRange:
|
case errInvalidRange:
|
||||||
writeErrorResponse(w, ErrInvalidCopyPartRange, url)
|
writeErrorResponse(w, ErrInvalidCopyPartRange, url, browser)
|
||||||
return
|
return
|
||||||
case errInvalidRangeSource:
|
case errInvalidRangeSource:
|
||||||
writeErrorResponse(w, ErrInvalidCopyPartRangeSource, url)
|
writeErrorResponse(w, ErrInvalidCopyPartRangeSource, url, browser)
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
writeErrorResponse(w, ErrInternalError, url)
|
writeErrorResponse(w, ErrInternalError, url, browser)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ func setRequestHeaderSizeLimitHandler(h http.Handler) http.Handler {
|
|||||||
// of the user-defined metadata to 2 KB.
|
// of the user-defined metadata to 2 KB.
|
||||||
func (h requestHeaderSizeLimitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h requestHeaderSizeLimitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
if isHTTPHeaderSizeTooLarge(r.Header) {
|
if isHTTPHeaderSizeTooLarge(r.Header) {
|
||||||
writeErrorResponse(w, ErrMetadataTooLarge, r.URL)
|
writeErrorResponse(w, ErrMetadataTooLarge, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.Handler.ServeHTTP(w, r)
|
h.Handler.ServeHTTP(w, r)
|
||||||
@ -134,7 +134,7 @@ func filterReservedMetadata(h http.Handler) http.Handler {
|
|||||||
// would be treated as metadata.
|
// would be treated as metadata.
|
||||||
func (h reservedMetadataHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h reservedMetadataHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
if containsReservedMetadata(r.Header) {
|
if containsReservedMetadata(r.Header) {
|
||||||
writeErrorResponse(w, ErrUnsupportedMetadata, r.URL)
|
writeErrorResponse(w, ErrUnsupportedMetadata, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.Handler.ServeHTTP(w, r)
|
h.Handler.ServeHTTP(w, r)
|
||||||
@ -300,7 +300,7 @@ func (h minioReservedBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
|
|||||||
// buckets
|
// buckets
|
||||||
bucketName, _ := urlPath2BucketObjectName(r.URL.Path)
|
bucketName, _ := urlPath2BucketObjectName(r.URL.Path)
|
||||||
if isMinioReservedBucket(bucketName) || isMinioMetaBucket(bucketName) {
|
if isMinioReservedBucket(bucketName) || isMinioMetaBucket(bucketName) {
|
||||||
writeErrorResponse(w, ErrAllAccessDisabled, r.URL)
|
writeErrorResponse(w, ErrAllAccessDisabled, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,14 +363,14 @@ func (h timeValidityHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// All our internal APIs are sensitive towards Date
|
// All our internal APIs are sensitive towards Date
|
||||||
// header, for all requests where Date header is not
|
// header, for all requests where Date header is not
|
||||||
// present we will reject such clients.
|
// present we will reject such clients.
|
||||||
writeErrorResponse(w, apiErr, r.URL)
|
writeErrorResponse(w, apiErr, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Verify if the request date header is shifted by less than globalMaxSkewTime parameter in the past
|
// Verify if the request date header is shifted by less than globalMaxSkewTime parameter in the past
|
||||||
// or in the future, reject request otherwise.
|
// or in the future, reject request otherwise.
|
||||||
curTime := UTCNow()
|
curTime := UTCNow()
|
||||||
if curTime.Sub(amzDate) > globalMaxSkewTime || amzDate.Sub(curTime) > globalMaxSkewTime {
|
if curTime.Sub(amzDate) > globalMaxSkewTime || amzDate.Sub(curTime) > globalMaxSkewTime {
|
||||||
writeErrorResponse(w, ErrRequestTimeTooSkewed, r.URL)
|
writeErrorResponse(w, ErrRequestTimeTooSkewed, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -485,20 +485,20 @@ func (h resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// If bucketName is present and not objectName check for bucket level resource queries.
|
// If bucketName is present and not objectName check for bucket level resource queries.
|
||||||
if bucketName != "" && objectName == "" {
|
if bucketName != "" && objectName == "" {
|
||||||
if ignoreNotImplementedBucketResources(r) {
|
if ignoreNotImplementedBucketResources(r) {
|
||||||
writeErrorResponse(w, ErrNotImplemented, r.URL)
|
writeErrorResponse(w, ErrNotImplemented, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If bucketName and objectName are present check for its resource queries.
|
// If bucketName and objectName are present check for its resource queries.
|
||||||
if bucketName != "" && objectName != "" {
|
if bucketName != "" && objectName != "" {
|
||||||
if ignoreNotImplementedObjectResources(r) {
|
if ignoreNotImplementedObjectResources(r) {
|
||||||
writeErrorResponse(w, ErrNotImplemented, r.URL)
|
writeErrorResponse(w, ErrNotImplemented, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// A put method on path "/" doesn't make sense, ignore it.
|
// A put method on path "/" doesn't make sense, ignore it.
|
||||||
if r.Method == http.MethodPut && r.URL.Path == "/" {
|
if r.Method == http.MethodPut && r.URL.Path == "/" {
|
||||||
writeErrorResponse(w, ErrNotImplemented, r.URL)
|
writeErrorResponse(w, ErrNotImplemented, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,14 +601,14 @@ func hasBadPathComponent(path string) bool {
|
|||||||
func (h pathValidityHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h pathValidityHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Check for bad components in URL path.
|
// Check for bad components in URL path.
|
||||||
if hasBadPathComponent(r.URL.Path) {
|
if hasBadPathComponent(r.URL.Path) {
|
||||||
writeErrorResponse(w, ErrInvalidResourceName, r.URL)
|
writeErrorResponse(w, ErrInvalidResourceName, r.URL, guessIsBrowserReq(r))
|
||||||
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.URL.Query() {
|
||||||
for _, v := range vv {
|
for _, v := range vv {
|
||||||
if hasBadPathComponent(v) {
|
if hasBadPathComponent(v) {
|
||||||
writeErrorResponse(w, ErrInvalidResourceName, r.URL)
|
writeErrorResponse(w, ErrInvalidResourceName, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -653,9 +653,9 @@ func (f bucketForwardingHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques
|
|||||||
sr, err := globalDNSConfig.Get(bucket)
|
sr, err := globalDNSConfig.Get(bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == dns.ErrNoEntriesFound {
|
if err == dns.ErrNoEntriesFound {
|
||||||
writeErrorResponse(w, ErrNoSuchBucket, r.URL)
|
writeErrorResponse(w, ErrNoSuchBucket, r.URL, guessIsBrowserReq(r))
|
||||||
} else {
|
} else {
|
||||||
writeErrorResponse(w, toAPIErrorCode(context.Background(), err), r.URL)
|
writeErrorResponse(w, toAPIErrorCode(context.Background(), err), r.URL, guessIsBrowserReq(r))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -716,7 +716,7 @@ func (l rateLimit) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// potential pileup on the server.
|
// potential pileup on the server.
|
||||||
if err := l.Wait(ctx); err != nil {
|
if err := l.Wait(ctx); err != nil {
|
||||||
// Send an S3 compatible error, SlowDown.
|
// Send an S3 compatible error, SlowDown.
|
||||||
writeErrorResponse(w, ErrSlowDown, r.URL)
|
writeErrorResponse(w, ErrSlowDown, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -768,7 +768,7 @@ type criticalErrorHandler struct{ handler http.Handler }
|
|||||||
func (h criticalErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h criticalErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err == logger.ErrCritical { // handle
|
if err := recover(); err == logger.ErrCritical { // handle
|
||||||
writeErrorResponse(w, ErrInternalError, r.URL)
|
writeErrorResponse(w, ErrInternalError, r.URL, guessIsBrowserReq(r))
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
panic(err) // forward other panic calls
|
panic(err) // forward other panic calls
|
||||||
}
|
}
|
||||||
@ -787,7 +787,7 @@ func (h sseTLSHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if r.Method == http.MethodHead {
|
if r.Method == http.MethodHead {
|
||||||
writeErrorResponseHeadersOnly(w, ErrInsecureSSECustomerRequest)
|
writeErrorResponseHeadersOnly(w, ErrInsecureSSECustomerRequest)
|
||||||
} else {
|
} else {
|
||||||
writeErrorResponse(w, ErrInsecureSSECustomerRequest, r.URL)
|
writeErrorResponse(w, ErrInsecureSSECustomerRequest, r.URL, guessIsBrowserReq(r))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -351,6 +351,6 @@ func getResource(path string, host string, domain string) (string, error) {
|
|||||||
|
|
||||||
// If none of the http routes match respond with MethodNotAllowed
|
// If none of the http routes match respond with MethodNotAllowed
|
||||||
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
|
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
writeErrorResponse(w, ErrMethodNotAllowed, r.URL)
|
writeErrorResponse(w, ErrMethodNotAllowed, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf
|
|||||||
if !ifModifiedSince(objInfo.ModTime, givenTime) {
|
if !ifModifiedSince(objInfo.ModTime, givenTime) {
|
||||||
// If the object is not modified since the specified time.
|
// If the object is not modified since the specified time.
|
||||||
writeHeaders()
|
writeHeaders()
|
||||||
writeErrorResponse(w, ErrPreconditionFailed, r.URL)
|
writeErrorResponse(w, ErrPreconditionFailed, r.URL, guessIsBrowserReq(r))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf
|
|||||||
if ifModifiedSince(objInfo.ModTime, givenTime) {
|
if ifModifiedSince(objInfo.ModTime, givenTime) {
|
||||||
// If the object is modified since the specified time.
|
// If the object is modified since the specified time.
|
||||||
writeHeaders()
|
writeHeaders()
|
||||||
writeErrorResponse(w, ErrPreconditionFailed, r.URL)
|
writeErrorResponse(w, ErrPreconditionFailed, r.URL, guessIsBrowserReq(r))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf
|
|||||||
if objInfo.ETag != "" && !isETagEqual(objInfo.ETag, ifMatchETagHeader) {
|
if objInfo.ETag != "" && !isETagEqual(objInfo.ETag, ifMatchETagHeader) {
|
||||||
// If the object ETag does not match with the specified ETag.
|
// If the object ETag does not match with the specified ETag.
|
||||||
writeHeaders()
|
writeHeaders()
|
||||||
writeErrorResponse(w, ErrPreconditionFailed, r.URL)
|
writeErrorResponse(w, ErrPreconditionFailed, r.URL, guessIsBrowserReq(r))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ func checkCopyObjectPreconditions(w http.ResponseWriter, r *http.Request, objInf
|
|||||||
if objInfo.ETag != "" && isETagEqual(objInfo.ETag, ifNoneMatchETagHeader) {
|
if objInfo.ETag != "" && isETagEqual(objInfo.ETag, ifNoneMatchETagHeader) {
|
||||||
// If the object ETag matches with the specified ETag.
|
// If the object ETag matches with the specified ETag.
|
||||||
writeHeaders()
|
writeHeaders()
|
||||||
writeErrorResponse(w, ErrPreconditionFailed, r.URL)
|
writeErrorResponse(w, ErrPreconditionFailed, r.URL, guessIsBrowserReq(r))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ func checkPreconditions(w http.ResponseWriter, r *http.Request, objInfo ObjectIn
|
|||||||
if ifModifiedSince(objInfo.ModTime, givenTime) {
|
if ifModifiedSince(objInfo.ModTime, givenTime) {
|
||||||
// If the object is modified since the specified time.
|
// If the object is modified since the specified time.
|
||||||
writeHeaders()
|
writeHeaders()
|
||||||
writeErrorResponse(w, ErrPreconditionFailed, r.URL)
|
writeErrorResponse(w, ErrPreconditionFailed, r.URL, guessIsBrowserReq(r))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,7 +187,7 @@ func checkPreconditions(w http.ResponseWriter, r *http.Request, objInfo ObjectIn
|
|||||||
if !isETagEqual(objInfo.ETag, ifMatchETagHeader) {
|
if !isETagEqual(objInfo.ETag, ifMatchETagHeader) {
|
||||||
// If the object ETag does not match with the specified ETag.
|
// If the object ETag does not match with the specified ETag.
|
||||||
writeHeaders()
|
writeHeaders()
|
||||||
writeErrorResponse(w, ErrPreconditionFailed, r.URL)
|
writeErrorResponse(w, ErrPreconditionFailed, r.URL, guessIsBrowserReq(r))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -768,7 +768,7 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Extract incoming metadata if any.
|
// Extract incoming metadata if any.
|
||||||
metadata, err := extractMetadata(context.Background(), r)
|
metadata, err := extractMetadata(context.Background(), r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErrorResponse(w, ErrInternalError, r.URL)
|
writeErrorResponse(w, ErrInternalError, r.URL, guessIsBrowserReq(r))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user