Skip to content

Commit d06ec64

Browse files
committed
Fix issue with spaces in the name
1 parent b1e21f0 commit d06ec64

File tree

6 files changed

+26
-143
lines changed

6 files changed

+26
-143
lines changed

api/admin_objects.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ type ObjectResponse struct {
5959
func getObjectsOptionsFromReq(request ObjectsRequest) (*objectsListOpts, error) {
6060
pOptions := objectsListOpts{
6161
BucketName: request.BucketName,
62-
Prefix: "",
63-
}
64-
65-
if request.Prefix != "" {
66-
pOptions.Prefix = SanitizeEncodedPrefix(request.Prefix)
62+
Prefix: request.Prefix,
6763
}
6864

6965
if request.Mode == "rewind" {

api/user_buckets.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,7 @@ func getBucketRewindResponse(session *models.Principal, params bucketApi.GetBuck
10301030
defer cancel()
10311031
prefix := ""
10321032
if params.Prefix != nil {
1033-
prefix = SanitizeEncodedPrefix(*params.Prefix)
1033+
prefix = *params.Prefix
10341034
}
10351035
s3Client, err := newS3BucketClient(session, params.BucketName, prefix, getClientIP(params.HTTPRequest))
10361036
if err != nil {

api/user_objects.go

Lines changed: 19 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,8 @@ func registerObjectsHandlers(api *operations.ConsoleAPI) {
7777
// download object
7878
api.ObjectDownloadObjectHandler = objectApi.DownloadObjectHandlerFunc(func(params objectApi.DownloadObjectParams, session *models.Principal) middleware.Responder {
7979
isFolder := false
80-
var prefix string
81-
if params.Prefix != "" {
82-
prefix = SanitizeEncodedPrefix(params.Prefix)
83-
}
8480

85-
folders := strings.Split(prefix, "/")
81+
folders := strings.Split(params.Prefix, "/")
8682
if folders[len(folders)-1] == "" {
8783
isFolder = true
8884
}
@@ -188,7 +184,7 @@ func getListObjectsResponse(session *models.Principal, params objectApi.ListObje
188184
var withVersions bool
189185
var withMetadata bool
190186
if params.Prefix != nil {
191-
prefix = SanitizeEncodedPrefix(*params.Prefix)
187+
prefix = *params.Prefix
192188
}
193189
if params.Recursive != nil {
194190
recursive = *params.Recursive
@@ -403,22 +399,18 @@ func parseRange(s string, size int64) ([]httpRange, error) {
403399

404400
func getDownloadObjectResponse(session *models.Principal, params objectApi.DownloadObjectParams) (middleware.Responder, *CodedAPIError) {
405401
ctx := params.HTTPRequest.Context()
406-
var prefix string
407402
mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest))
408403
if err != nil {
409404
return nil, ErrorWithContext(ctx, err)
410405
}
411-
if params.Prefix != "" {
412-
prefix = SanitizeEncodedPrefix(params.Prefix)
413-
}
414406

415407
opts := minio.GetObjectOptions{}
416408

417409
if params.VersionID != nil && *params.VersionID != "" {
418410
opts.VersionID = *params.VersionID
419411
}
420412

421-
resp, err := mClient.GetObject(ctx, params.BucketName, prefix, opts)
413+
resp, err := mClient.GetObject(ctx, params.BucketName, params.Prefix, opts)
422414
if err != nil {
423415
return nil, ErrorWithContext(ctx, err)
424416
}
@@ -431,7 +423,7 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl
431423

432424
// indicate it's a download / inline content to the browser, and the size of the object
433425
var filename string
434-
prefixElements := strings.Split(prefix, "/")
426+
prefixElements := strings.Split(params.Prefix, "/")
435427
if len(prefixElements) > 0 && overrideName == "" {
436428
if prefixElements[len(prefixElements)-1] == "" {
437429
filename = prefixElements[len(prefixElements)-2]
@@ -448,7 +440,7 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl
448440
stat, err := resp.Stat()
449441
if err != nil {
450442
minErr := minio.ToErrorResponse(err)
451-
fmtError := ErrorWithContext(ctx, fmt.Errorf("failed to get Stat() response from server for %s (version %s): %v", prefix, opts.VersionID, minErr.Error()))
443+
fmtError := ErrorWithContext(ctx, fmt.Errorf("failed to get Stat() response from server for %s (version %s): %v", params.Prefix, opts.VersionID, minErr.Error()))
452444
http.Error(rw, fmtError.APIError.DetailedMessage, http.StatusInternalServerError)
453445
return
454446
}
@@ -510,13 +502,9 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl
510502

511503
func getDownloadFolderResponse(session *models.Principal, params objectApi.DownloadObjectParams) (middleware.Responder, *CodedAPIError) {
512504
ctx := params.HTTPRequest.Context()
513-
var prefix string
514505
mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest))
515-
if params.Prefix != "" {
516-
prefix = SanitizeEncodedPrefix(params.Prefix)
517-
}
518506

519-
folders := strings.Split(prefix, "/")
507+
folders := strings.Split(params.Prefix, "/")
520508

521509
if err != nil {
522510
return nil, ErrorWithContext(ctx, err)
@@ -526,7 +514,7 @@ func getDownloadFolderResponse(session *models.Principal, params objectApi.Downl
526514
ctx: ctx,
527515
client: minioClient,
528516
bucketName: params.BucketName,
529-
prefix: prefix,
517+
prefix: params.Prefix,
530518
recursive: true,
531519
withVersions: false,
532520
withMetadata: false,
@@ -547,7 +535,7 @@ func getDownloadFolderResponse(session *models.Principal, params objectApi.Downl
547535
defer zipw.Close()
548536

549537
for i, obj := range objects {
550-
name := folder + objects[i].Name[len(prefix)-1:]
538+
name := folder + objects[i].Name[len(params.Prefix)-1:]
551539
object, err := mClient.GetObject(ctx, params.BucketName, obj.Name, minio.GetObjectOptions{})
552540
if err != nil {
553541
// Ignore errors, move to next
@@ -577,12 +565,8 @@ func getDownloadFolderResponse(session *models.Principal, params objectApi.Downl
577565
defer resp.Close()
578566

579567
// indicate it's a download / inline content to the browser, and the size of the object
580-
var prefixPath string
581568
var filename string
582-
if params.Prefix != "" {
583-
prefixPath = SanitizeEncodedPrefix(params.Prefix)
584-
}
585-
prefixElements := strings.Split(prefixPath, "/")
569+
prefixElements := strings.Split(params.Prefix, "/")
586570
if len(prefixElements) > 0 {
587571
if prefixElements[len(prefixElements)-1] == "" {
588572
filename = prefixElements[len(prefixElements)-2]
@@ -735,11 +719,7 @@ func getMultipleFilesDownloadResponse(session *models.Principal, params objectAp
735719
func getDeleteObjectResponse(session *models.Principal, params objectApi.DeleteObjectParams) *CodedAPIError {
736720
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
737721
defer cancel()
738-
var prefix string
739-
if params.Prefix != "" {
740-
prefix = SanitizeEncodedPrefix(params.Prefix)
741-
}
742-
s3Client, err := newS3BucketClient(session, params.BucketName, prefix, getClientIP(params.HTTPRequest))
722+
s3Client, err := newS3BucketClient(session, params.BucketName, params.Prefix, getClientIP(params.HTTPRequest))
743723
if err != nil {
744724
return ErrorWithContext(ctx, err)
745725
}
@@ -772,7 +752,7 @@ func getDeleteObjectResponse(session *models.Principal, params objectApi.DeleteO
772752
return ErrorWithContext(ctx, err)
773753
}
774754

775-
err = deleteObjects(ctx, mcClient, params.BucketName, prefix, version, rec, allVersions, nonCurrentVersions, bypass)
755+
err = deleteObjects(ctx, mcClient, params.BucketName, params.Prefix, version, rec, allVersions, nonCurrentVersions, bypass)
776756
if err != nil {
777757
return ErrorWithContext(ctx, err)
778758
}
@@ -963,7 +943,7 @@ func getUploadObjectResponse(session *models.Principal, params objectApi.PostBuc
963943
func uploadFiles(ctx context.Context, client MinioClient, params objectApi.PostBucketsBucketNameObjectsUploadParams) error {
964944
var prefix string
965945
if params.Prefix != nil {
966-
prefix = SanitizeEncodedPrefix(*params.Prefix)
946+
prefix = *params.Prefix
967947
// trim any leading '/', since that is not expected
968948
// for any object.
969949
prefix = strings.TrimPrefix(prefix, "/")
@@ -1008,11 +988,7 @@ func uploadFiles(ctx context.Context, client MinioClient, params objectApi.PostB
1008988
func getShareObjectResponse(session *models.Principal, params objectApi.ShareObjectParams) (*string, *CodedAPIError) {
1009989
ctx := params.HTTPRequest.Context()
1010990
clientIP := utils.ClientIPFromContext(ctx)
1011-
var prefix string
1012-
if params.Prefix != "" {
1013-
prefix = SanitizeEncodedPrefix(params.Prefix)
1014-
}
1015-
s3Client, err := newS3BucketClient(session, params.BucketName, prefix, clientIP)
991+
s3Client, err := newS3BucketClient(session, params.BucketName, params.Prefix, clientIP)
1016992
if err != nil {
1017993
return nil, ErrorWithContext(ctx, err)
1018994
}
@@ -1073,11 +1049,7 @@ func getSetObjectLegalHoldResponse(session *models.Principal, params objectApi.P
10731049
// create a minioClient interface implementation
10741050
// defining the client to be used
10751051
minioClient := minioClient{client: mClient}
1076-
var prefix string
1077-
if params.Prefix != "" {
1078-
prefix = SanitizeEncodedPrefix(params.Prefix)
1079-
}
1080-
err = setObjectLegalHold(ctx, minioClient, params.BucketName, prefix, params.VersionID, *params.Body.Status)
1052+
err = setObjectLegalHold(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID, *params.Body.Status)
10811053
if err != nil {
10821054
return ErrorWithContext(ctx, err)
10831055
}
@@ -1103,11 +1075,7 @@ func getSetObjectRetentionResponse(session *models.Principal, params objectApi.P
11031075
// create a minioClient interface implementation
11041076
// defining the client to be used
11051077
minioClient := minioClient{client: mClient}
1106-
var prefix string
1107-
if params.Prefix != "" {
1108-
prefix = SanitizeEncodedPrefix(params.Prefix)
1109-
}
1110-
err = setObjectRetention(ctx, minioClient, params.BucketName, params.VersionID, prefix, params.Body)
1078+
err = setObjectRetention(ctx, minioClient, params.BucketName, params.VersionID, params.Prefix, params.Body)
11111079
if err != nil {
11121080
return ErrorWithContext(ctx, err)
11131081
}
@@ -1150,11 +1118,7 @@ func deleteObjectRetentionResponse(session *models.Principal, params objectApi.D
11501118
// create a minioClient interface implementation
11511119
// defining the client to be used
11521120
minioClient := minioClient{client: mClient}
1153-
var prefix string
1154-
if params.Prefix != "" {
1155-
prefix = SanitizeEncodedPrefix(params.Prefix)
1156-
}
1157-
err = deleteObjectRetention(ctx, minioClient, params.BucketName, prefix, params.VersionID)
1121+
err = deleteObjectRetention(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID)
11581122
if err != nil {
11591123
return ErrorWithContext(ctx, err)
11601124
}
@@ -1179,11 +1143,7 @@ func getPutObjectTagsResponse(session *models.Principal, params objectApi.PutObj
11791143
// create a minioClient interface implementation
11801144
// defining the client to be used
11811145
minioClient := minioClient{client: mClient}
1182-
var prefix string
1183-
if params.Prefix != "" {
1184-
prefix = SanitizeEncodedPrefix(params.Prefix)
1185-
}
1186-
err = putObjectTags(ctx, minioClient, params.BucketName, prefix, params.VersionID, params.Body.Tags)
1146+
err = putObjectTags(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID, params.Body.Tags)
11871147
if err != nil {
11881148
return ErrorWithContext(ctx, err)
11891149
}
@@ -1211,13 +1171,7 @@ func getPutObjectRestoreResponse(session *models.Principal, params objectApi.Put
12111171
// create a minioClient interface implementation
12121172
// defining the client to be used
12131173
minioClient := minioClient{client: mClient}
1214-
1215-
var prefix string
1216-
if params.Prefix != "" {
1217-
prefix = SanitizeEncodedPrefix(params.Prefix)
1218-
}
1219-
1220-
err = restoreObject(ctx, minioClient, params.BucketName, prefix, params.VersionID)
1174+
err = restoreObject(ctx, minioClient, params.BucketName, params.Prefix, params.VersionID)
12211175
if err != nil {
12221176
return ErrorWithContext(ctx, err)
12231177
}
@@ -1261,18 +1215,12 @@ func getObjectMetadataResponse(session *models.Principal, params objectApi.GetOb
12611215
// create a minioClient interface implementation
12621216
// defining the client to be used
12631217
minioClient := minioClient{client: mClient}
1264-
var prefix string
12651218
var versionID string
1266-
1267-
if params.Prefix != "" {
1268-
prefix = SanitizeEncodedPrefix(params.Prefix)
1269-
}
1270-
12711219
if params.VersionID != nil {
12721220
versionID = *params.VersionID
12731221
}
12741222

1275-
objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, prefix, versionID)
1223+
objectInfo, err := getObjectInfo(ctx, minioClient, params.BucketName, params.Prefix, versionID)
12761224
if err != nil {
12771225
return nil, ErrorWithContext(ctx, err)
12781226
}

api/utils.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,6 @@ func ValidateEncodedStyles(encodedStyles string) error {
211211
return nil
212212
}
213213

214-
// SanitizeEncodedPrefix replaces spaces for + since those are lost when you do GET parameters
215-
func SanitizeEncodedPrefix(rawPrefix string) string {
216-
return strings.ReplaceAll(rawPrefix, " ", "+")
217-
}
218-
219214
var safeMimeTypes = []string{
220215
"image/jpeg",
221216
"image/apng",

api/utils_test.go

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -153,37 +153,6 @@ func TestExpireSessionCookie(t *testing.T) {
153153
}
154154
}
155155

156-
func TestSanitizeEncodedPrefix(t *testing.T) {
157-
type args struct {
158-
rawPrefix string
159-
}
160-
tests := []struct {
161-
name string
162-
args args
163-
want string
164-
}{
165-
{
166-
name: "replace spaces with +",
167-
args: args{
168-
rawPrefix: "hello world",
169-
},
170-
want: "hello+world",
171-
},
172-
{
173-
name: "replace spaces with +",
174-
args: args{
175-
rawPrefix: " hello-world ",
176-
},
177-
want: "+++hello-world+++",
178-
},
179-
}
180-
for _, tt := range tests {
181-
t.Run(tt.name, func(_ *testing.T) {
182-
assert.Equalf(t, tt.want, SanitizeEncodedPrefix(tt.args.rawPrefix), "SanitizeEncodedPrefix(%v)", tt.args.rawPrefix)
183-
})
184-
}
185-
}
186-
187156
func Test_isSafeToPreview(t *testing.T) {
188157
type args struct {
189158
str string
@@ -293,27 +262,3 @@ func TestValidateEncodedStyles(t *testing.T) {
293262
})
294263
}
295264
}
296-
297-
func TestSanitizeEncodedPrefix1(t *testing.T) {
298-
type args struct {
299-
rawPrefix string
300-
}
301-
tests := []struct {
302-
name string
303-
args args
304-
want string
305-
}{
306-
{
307-
name: "input sanitized",
308-
args: args{
309-
rawPrefix: "x y",
310-
},
311-
want: "x+y",
312-
},
313-
}
314-
for _, tt := range tests {
315-
t.Run(tt.name, func(_ *testing.T) {
316-
assert.Equalf(t, tt.want, SanitizeEncodedPrefix(tt.args.rawPrefix), "SanitizeEncodedPrefix(%v)", tt.args.rawPrefix)
317-
})
318-
}
319-
}

web-app/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/ListObjects.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,10 @@ const ListObjects = () => {
231231

232232
const bucketName = params.bucketName || "";
233233
const pathSegment = location.pathname.split(`/browser/${bucketName}/`);
234-
const internalPaths = pathSegment.length === 2 ? pathSegment[1] : "";
234+
const internalPaths =
235+
pathSegment.length === 2 ? decodeURIComponent(pathSegment[1]) : "";
235236

236-
const pageTitle = decodeURIComponent(internalPaths);
237-
const currentPath = pageTitle.split("/").filter((i: string) => i !== "");
237+
const currentPath = internalPaths.split("/").filter((i: string) => i !== "");
238238

239239
let uploadPath = [bucketName];
240240
if (currentPath.length > 0) {
@@ -803,8 +803,7 @@ const ListObjects = () => {
803803
if (detailsOpen && selectedInternalPaths !== null) {
804804
// We change URL to be the contained folder
805805

806-
const decodedPath = decodeURIComponent(internalPaths);
807-
const splitURLS = decodedPath.split("/");
806+
const splitURLS = internalPaths.split("/");
808807

809808
// We remove the last section of the URL as it should be a file
810809
splitURLS.pop();
@@ -1215,7 +1214,7 @@ const ListObjects = () => {
12151214
>
12161215
<BrowserBreadcrumbs
12171216
bucketName={bucketName}
1218-
internalPaths={pageTitle}
1217+
internalPaths={internalPaths}
12191218
additionalOptions={
12201219
!isVersioningApplied || rewindEnabled ? null : (
12211220
<Checkbox

0 commit comments

Comments
 (0)