Use automatic URI encoding (#3352)
This commit is contained in:
@@ -18,8 +18,6 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
b64 "encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -79,19 +77,8 @@ func registerObjectsHandlers(api *operations.ConsoleAPI) {
|
||||
// download object
|
||||
api.ObjectDownloadObjectHandler = objectApi.DownloadObjectHandlerFunc(func(params objectApi.DownloadObjectParams, session *models.Principal) middleware.Responder {
|
||||
isFolder := false
|
||||
ctx := params.HTTPRequest.Context()
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
apiErr := ErrorWithContext(ctx, err)
|
||||
return objectApi.NewDownloadObjectDefault(400).WithPayload(apiErr.APIError)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
|
||||
folders := strings.Split(prefix, "/")
|
||||
folders := strings.Split(params.Prefix, "/")
|
||||
if folders[len(folders)-1] == "" {
|
||||
isFolder = true
|
||||
}
|
||||
@@ -197,12 +184,7 @@ func getListObjectsResponse(session *models.Principal, params objectApi.ListObje
|
||||
var withVersions bool
|
||||
var withMetadata bool
|
||||
if params.Prefix != nil {
|
||||
encodedPrefix := SanitizeEncodedPrefix(*params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
prefix = *params.Prefix
|
||||
}
|
||||
if params.Recursive != nil {
|
||||
recursive = *params.Recursive
|
||||
@@ -417,19 +399,10 @@ func parseRange(s string, size int64) ([]httpRange, error) {
|
||||
|
||||
func getDownloadObjectResponse(session *models.Principal, params objectApi.DownloadObjectParams) (middleware.Responder, *CodedAPIError) {
|
||||
ctx := params.HTTPRequest.Context()
|
||||
var prefix string
|
||||
mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest))
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
|
||||
opts := minio.GetObjectOptions{}
|
||||
|
||||
@@ -437,7 +410,7 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl
|
||||
opts.VersionID = *params.VersionID
|
||||
}
|
||||
|
||||
resp, err := mClient.GetObject(ctx, params.BucketName, prefix, opts)
|
||||
resp, err := mClient.GetObject(ctx, params.BucketName, params.Prefix, opts)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -446,19 +419,11 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl
|
||||
defer resp.Close()
|
||||
|
||||
isPreview := params.Preview != nil && *params.Preview
|
||||
// override filename is set
|
||||
decodeOverride, err := base64.StdEncoding.DecodeString(*params.OverrideFileName)
|
||||
if err != nil {
|
||||
fmtError := ErrorWithContext(ctx, fmt.Errorf("unable to decode OverrideFileName: %v", err))
|
||||
http.Error(rw, fmtError.APIError.DetailedMessage, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
overrideName := string(decodeOverride)
|
||||
overrideName := *params.OverrideFileName
|
||||
|
||||
// indicate it's a download / inline content to the browser, and the size of the object
|
||||
var filename string
|
||||
prefixElements := strings.Split(prefix, "/")
|
||||
prefixElements := strings.Split(params.Prefix, "/")
|
||||
if len(prefixElements) > 0 && overrideName == "" {
|
||||
if prefixElements[len(prefixElements)-1] == "" {
|
||||
filename = prefixElements[len(prefixElements)-2]
|
||||
@@ -475,7 +440,7 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl
|
||||
stat, err := resp.Stat()
|
||||
if err != nil {
|
||||
minErr := minio.ToErrorResponse(err)
|
||||
fmtError := ErrorWithContext(ctx, fmt.Errorf("failed to get Stat() response from server for %s (version %s): %v", prefix, opts.VersionID, minErr.Error()))
|
||||
fmtError := ErrorWithContext(ctx, fmt.Errorf("failed to get Stat() response from server for %s (version %s): %v", params.Prefix, opts.VersionID, minErr.Error()))
|
||||
http.Error(rw, fmtError.APIError.DetailedMessage, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -537,18 +502,9 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl
|
||||
|
||||
func getDownloadFolderResponse(session *models.Principal, params objectApi.DownloadObjectParams) (middleware.Responder, *CodedAPIError) {
|
||||
ctx := params.HTTPRequest.Context()
|
||||
var prefix string
|
||||
mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest))
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
|
||||
folders := strings.Split(prefix, "/")
|
||||
folders := strings.Split(params.Prefix, "/")
|
||||
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
@@ -558,7 +514,7 @@ func getDownloadFolderResponse(session *models.Principal, params objectApi.Downl
|
||||
ctx: ctx,
|
||||
client: minioClient,
|
||||
bucketName: params.BucketName,
|
||||
prefix: prefix,
|
||||
prefix: params.Prefix,
|
||||
recursive: true,
|
||||
withVersions: false,
|
||||
withMetadata: false,
|
||||
@@ -579,7 +535,7 @@ func getDownloadFolderResponse(session *models.Principal, params objectApi.Downl
|
||||
defer zipw.Close()
|
||||
|
||||
for i, obj := range objects {
|
||||
name := folder + objects[i].Name[len(prefix)-1:]
|
||||
name := folder + objects[i].Name[len(params.Prefix)-1:]
|
||||
object, err := mClient.GetObject(ctx, params.BucketName, obj.Name, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
// Ignore errors, move to next
|
||||
@@ -609,20 +565,8 @@ func getDownloadFolderResponse(session *models.Principal, params objectApi.Downl
|
||||
defer resp.Close()
|
||||
|
||||
// indicate it's a download / inline content to the browser, and the size of the object
|
||||
var prefixPath string
|
||||
var filename string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
fmtError := ErrorWithContext(ctx, fmt.Errorf("unable to parse encoded prefix %s: %v", encodedPrefix, err))
|
||||
http.Error(rw, fmtError.APIError.DetailedMessage, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
prefixPath = string(decodedPrefix)
|
||||
}
|
||||
prefixElements := strings.Split(prefixPath, "/")
|
||||
prefixElements := strings.Split(params.Prefix, "/")
|
||||
if len(prefixElements) > 0 {
|
||||
if prefixElements[len(prefixElements)-1] == "" {
|
||||
filename = prefixElements[len(prefixElements)-2]
|
||||
@@ -775,16 +719,7 @@ func getMultipleFilesDownloadResponse(session *models.Principal, params objectAp
|
||||
func getDeleteObjectResponse(session *models.Principal, params objectApi.DeleteObjectParams) *CodedAPIError {
|
||||
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
|
||||
defer cancel()
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
s3Client, err := newS3BucketClient(session, params.BucketName, prefix, getClientIP(params.HTTPRequest))
|
||||
s3Client, err := newS3BucketClient(session, params.BucketName, params.Prefix, getClientIP(params.HTTPRequest))
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -817,7 +752,7 @@ func getDeleteObjectResponse(session *models.Principal, params objectApi.DeleteO
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
|
||||
err = deleteObjects(ctx, mcClient, params.BucketName, prefix, version, rec, allVersions, nonCurrentVersions, bypass)
|
||||
err = deleteObjects(ctx, mcClient, params.BucketName, params.Prefix, version, rec, allVersions, nonCurrentVersions, bypass)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -1008,12 +943,7 @@ func getUploadObjectResponse(session *models.Principal, params objectApi.PostBuc
|
||||
func uploadFiles(ctx context.Context, client MinioClient, params objectApi.PostBucketsBucketNameObjectsUploadParams) error {
|
||||
var prefix string
|
||||
if params.Prefix != nil {
|
||||
encodedPrefix := SanitizeEncodedPrefix(*params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
prefix = *params.Prefix
|
||||
// trim any leading '/', since that is not expected
|
||||
// for any object.
|
||||
prefix = strings.TrimPrefix(prefix, "/")
|
||||
@@ -1058,16 +988,7 @@ func uploadFiles(ctx context.Context, client MinioClient, params objectApi.PostB
|
||||
func getShareObjectResponse(session *models.Principal, params objectApi.ShareObjectParams) (*string, *CodedAPIError) {
|
||||
ctx := params.HTTPRequest.Context()
|
||||
clientIP := utils.ClientIPFromContext(ctx)
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
s3Client, err := newS3BucketClient(session, params.BucketName, prefix, clientIP)
|
||||
s3Client, err := newS3BucketClient(session, params.BucketName, params.Prefix, clientIP)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -1086,7 +1007,7 @@ func getShareObjectResponse(session *models.Principal, params objectApi.ShareObj
|
||||
return url, nil
|
||||
}
|
||||
|
||||
func getShareObjectURL(ctx context.Context, client MCClient, r *http.Request, versionID string, duration string) (url *string, err error) {
|
||||
func getShareObjectURL(ctx context.Context, client MCClient, r *http.Request, versionID string, duration string) (*string, error) {
|
||||
// default duration 7d if not defined
|
||||
if strings.TrimSpace(duration) == "" {
|
||||
duration = "168h"
|
||||
@@ -1100,9 +1021,8 @@ func getShareObjectURL(ctx context.Context, client MCClient, r *http.Request, ve
|
||||
return nil, pErr.Cause
|
||||
}
|
||||
|
||||
encodedMinIOURL := b64.URLEncoding.EncodeToString([]byte(minioURL))
|
||||
requestURL := getRequestURLWithScheme(r)
|
||||
objURL := fmt.Sprintf("%s/api/v1/download-shared-object/%s", requestURL, encodedMinIOURL)
|
||||
objURL := fmt.Sprintf("%s/api/v1/download-shared-object/%s", requestURL, url.PathEscape(minioURL))
|
||||
return &objURL, nil
|
||||
}
|
||||
|
||||
@@ -1129,16 +1049,7 @@ func getSetObjectLegalHoldResponse(session *models.Principal, params objectApi.P
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
err = setObjectLegalHold(ctx, minioClient, params.BucketName, prefix, params.VersionID, *params.Body.Status)
|
||||
err = setObjectLegalHold(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID, *params.Body.Status)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -1164,16 +1075,7 @@ func getSetObjectRetentionResponse(session *models.Principal, params objectApi.P
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
err = setObjectRetention(ctx, minioClient, params.BucketName, params.VersionID, prefix, params.Body)
|
||||
err = setObjectRetention(ctx, minioClient, params.BucketName, params.VersionID, params.Prefix, params.Body)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -1216,16 +1118,7 @@ func deleteObjectRetentionResponse(session *models.Principal, params objectApi.D
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
err = deleteObjectRetention(ctx, minioClient, params.BucketName, prefix, params.VersionID)
|
||||
err = deleteObjectRetention(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -1250,16 +1143,7 @@ func getPutObjectTagsResponse(session *models.Principal, params objectApi.PutObj
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
err = putObjectTags(ctx, minioClient, params.BucketName, prefix, params.VersionID, params.Body.Tags)
|
||||
err = putObjectTags(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID, params.Body.Tags)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -1287,18 +1171,7 @@ func getPutObjectRestoreResponse(session *models.Principal, params objectApi.Put
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
|
||||
var prefix string
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
|
||||
err = restoreObject(ctx, minioClient, params.BucketName, prefix, params.VersionID)
|
||||
err = restoreObject(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID)
|
||||
if err != nil {
|
||||
return ErrorWithContext(ctx, err)
|
||||
}
|
||||
@@ -1342,23 +1215,12 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
var prefix string
|
||||
var versionID string
|
||||
|
||||
if params.Prefix != "" {
|
||||
encodedPrefix := SanitizeEncodedPrefix(params.Prefix)
|
||||
decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
prefix = string(decodedPrefix)
|
||||
}
|
||||
|
||||
if params.VersionID != nil {
|
||||
versionID = *params.VersionID
|
||||
}
|
||||
|
||||
objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, prefix, versionID)
|
||||
objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, params.Prefix, versionID)
|
||||
if err != nil {
|
||||
return nil, ErrorWithContext(ctx, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user