listV2: Continuation and NextContinuation tokens are encoded with base64 (#8337)

Minio V2 listing uses object names/prefixes as continuation tokens. This
is problematic when object names contain some characters that are forbidden
in XML documents. This PR will use base64 encoded form of continuation
and next continuation tokens to address that corner case.
master
Anis Elleuch 5 years ago committed by kannappanr
parent 82b9f2c931
commit 61927d228c
  1. 11
      cmd/api-resources.go
  2. 4
      cmd/api-resources_test.go
  3. 5
      cmd/api-response.go

@ -17,6 +17,7 @@
package cmd package cmd
import ( import (
"encoding/base64"
"net/url" "net/url"
"strconv" "strconv"
) )
@ -86,11 +87,19 @@ func getListObjectsV2Args(values url.Values) (prefix, token, startAfter, delimit
} }
prefix = values.Get("prefix") prefix = values.Get("prefix")
token = values.Get("continuation-token")
startAfter = values.Get("start-after") startAfter = values.Get("start-after")
delimiter = values.Get("delimiter") delimiter = values.Get("delimiter")
fetchOwner = values.Get("fetch-owner") == "true" fetchOwner = values.Get("fetch-owner") == "true"
encodingType = values.Get("encoding-type") encodingType = values.Get("encoding-type")
if token = values.Get("continuation-token"); token != "" {
decodedToken, err := base64.StdEncoding.DecodeString(token)
if err != nil {
errCode = ErrIncorrectContinuationToken
return
}
token = string(decodedToken)
}
return return
} }

@ -34,7 +34,7 @@ func TestListObjectsV2Resources(t *testing.T) {
{ {
values: url.Values{ values: url.Values{
"prefix": []string{"photos/"}, "prefix": []string{"photos/"},
"continuation-token": []string{"token"}, "continuation-token": []string{"dG9rZW4="},
"start-after": []string{"start-after"}, "start-after": []string{"start-after"},
"delimiter": []string{SlashSeparator}, "delimiter": []string{SlashSeparator},
"fetch-owner": []string{"true"}, "fetch-owner": []string{"true"},
@ -53,7 +53,7 @@ func TestListObjectsV2Resources(t *testing.T) {
{ {
values: url.Values{ values: url.Values{
"prefix": []string{"photos/"}, "prefix": []string{"photos/"},
"continuation-token": []string{"token"}, "continuation-token": []string{"dG9rZW4="},
"start-after": []string{"start-after"}, "start-after": []string{"start-after"},
"delimiter": []string{SlashSeparator}, "delimiter": []string{SlashSeparator},
"fetch-owner": []string{"true"}, "fetch-owner": []string{"true"},

@ -18,6 +18,7 @@ package cmd
import ( import (
"context" "context"
"encoding/base64"
"encoding/xml" "encoding/xml"
"net/http" "net/http"
"net/url" "net/url"
@ -498,8 +499,8 @@ func generateListObjectsV2Response(bucket, prefix, token, nextToken, startAfter,
data.Delimiter = s3EncodeName(delimiter, encodingType) data.Delimiter = s3EncodeName(delimiter, encodingType)
data.Prefix = s3EncodeName(prefix, encodingType) data.Prefix = s3EncodeName(prefix, encodingType)
data.MaxKeys = maxKeys data.MaxKeys = maxKeys
data.ContinuationToken = s3EncodeName(token, encodingType) data.ContinuationToken = base64.StdEncoding.EncodeToString([]byte(token))
data.NextContinuationToken = s3EncodeName(nextToken, encodingType) data.NextContinuationToken = base64.StdEncoding.EncodeToString([]byte(nextToken))
data.IsTruncated = isTruncated data.IsTruncated = isTruncated
for _, prefix := range prefixes { for _, prefix := range prefixes {
var prefixItem = CommonPrefix{} var prefixItem = CommonPrefix{}

Loading…
Cancel
Save