diff --git a/cmd/bucket-handlers-listobjects.go b/cmd/bucket-handlers-listobjects.go index 81db8b65c..6381ce837 100644 --- a/cmd/bucket-handlers-listobjects.go +++ b/cmd/bucket-handlers-listobjects.go @@ -18,7 +18,6 @@ package cmd import ( "net/http" - "strings" "github.com/gorilla/mux" ) @@ -44,7 +43,7 @@ func validateListObjectsArgs(prefix, marker, delimiter string, maxKeys int) APIE // Marker is set validate pre-condition. if marker != "" { // Marker not common with prefix is not implemented. - if !strings.HasPrefix(marker, prefix) { + if !hasPrefix(marker, prefix) { return ErrNotImplemented } } diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index e6f5c6871..660396a3a 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -165,7 +165,7 @@ func (api objectAPIHandlers) ListMultipartUploadsHandler(w http.ResponseWriter, } if keyMarker != "" { // Marker not common with prefix is not implemented. - if !strings.HasPrefix(keyMarker, prefix) { + if !hasPrefix(keyMarker, prefix) { writeErrorResponse(w, ErrNotImplemented, r.URL) return } diff --git a/cmd/bucket-policy-handlers.go b/cmd/bucket-policy-handlers.go index 00b3b5d2b..d68e2537f 100644 --- a/cmd/bucket-policy-handlers.go +++ b/cmd/bucket-policy-handlers.go @@ -21,6 +21,8 @@ import ( "io" "io/ioutil" "net/http" + "runtime" + "strings" humanize "github.com/dustin/go-humanize" mux "github.com/gorilla/mux" @@ -63,6 +65,10 @@ func bucketPolicyActionMatch(action string, statement policyStatement) bool { // Match function matches wild cards in 'pattern' for resource. func resourceMatch(pattern, resource string) bool { + if runtime.GOOS == "windows" { + // For windows specifically make sure we are case insensitive. + return wildcard.Match(strings.ToLower(pattern), strings.ToLower(resource)) + } return wildcard.Match(pattern, resource) } diff --git a/cmd/bucket-policy-parser.go b/cmd/bucket-policy-parser.go index 7af5e5bf4..5d98b8690 100644 --- a/cmd/bucket-policy-parser.go +++ b/cmd/bucket-policy-parser.go @@ -111,12 +111,12 @@ func isValidResources(resources set.StringSet) (err error) { return err } for resource := range resources { - if !strings.HasPrefix(resource, bucketARNPrefix) { + if !hasPrefix(resource, bucketARNPrefix) { err = errors.New("Unsupported resource style found: ‘" + resource + "’, please validate your policy document") return err } resourceSuffix := strings.SplitAfter(resource, bucketARNPrefix)[1] - if len(resourceSuffix) == 0 || strings.HasPrefix(resourceSuffix, "/") { + if len(resourceSuffix) == 0 || hasPrefix(resourceSuffix, "/") { err = errors.New("Invalid resource style found: ‘" + resource + "’, please validate your policy document") return err } @@ -282,7 +282,7 @@ func checkBucketPolicyResources(bucket string, bucketPolicy *bucketPolicy) APIEr // nesting. Reject such rules. for _, otherResource := range resources { // Common prefix reject such rules. - if strings.HasPrefix(otherResource, resource) { + if hasPrefix(otherResource, resource) { return ErrPolicyNesting } } diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 974045687..229e752b4 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -141,8 +141,8 @@ func setBrowserCacheControlHandler(h http.Handler) http.Handler { func (h cacheControlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method == httpGET && guessIsBrowserReq(r) && globalIsBrowserEnabled { // For all browser requests set appropriate Cache-Control policies - if strings.HasPrefix(r.URL.Path, reservedBucket+"/") { - if strings.HasSuffix(r.URL.Path, ".js") || r.URL.Path == reservedBucket+"/favicon.ico" { + if hasPrefix(r.URL.Path, reservedBucket+"/") { + if hasSuffix(r.URL.Path, ".js") || r.URL.Path == reservedBucket+"/favicon.ico" { // For assets set cache expiry of one year. For each release, the name // of the asset name will change and hence it can not be served from cache. w.Header().Set("Cache-Control", "max-age=31536000") diff --git a/cmd/lockinfo-handlers.go b/cmd/lockinfo-handlers.go index 3a9e093f9..aa3fb234d 100644 --- a/cmd/lockinfo-handlers.go +++ b/cmd/lockinfo-handlers.go @@ -16,10 +16,7 @@ package cmd -import ( - "strings" - "time" -) +import "time" // SystemLockState - Structure to fill the lock state of entire object storage. // That is the total locks held, total calls blocked on locks and state of all the locks for the entire system. @@ -82,7 +79,7 @@ func listLocksInfo(bucket, prefix string, duration time.Duration) []VolumeLockIn continue } // N B empty prefix matches all param.path. - if !strings.HasPrefix(param.path, prefix) { + if !hasPrefix(param.path, prefix) { continue } diff --git a/cmd/notifiers.go b/cmd/notifiers.go index b7b5ec496..f1f1c4cbc 100644 --- a/cmd/notifiers.go +++ b/cmd/notifiers.go @@ -18,7 +18,6 @@ package cmd import ( "errors" - "strings" "github.com/minio/minio/pkg/wildcard" ) @@ -206,9 +205,9 @@ func filterRuleMatch(object string, frs []filterRule) bool { var prefixMatch, suffixMatch = true, true for _, fr := range frs { if isValidFilterNamePrefix(fr.Name) { - prefixMatch = strings.HasPrefix(object, fr.Value) + prefixMatch = hasPrefix(object, fr.Value) } else if isValidFilterNameSuffix(fr.Name) { - suffixMatch = strings.HasSuffix(object, fr.Value) + suffixMatch = hasSuffix(object, fr.Value) } } return prefixMatch && suffixMatch diff --git a/cmd/object-api-input-checks.go b/cmd/object-api-input-checks.go index 74b736e54..62e77ab16 100644 --- a/cmd/object-api-input-checks.go +++ b/cmd/object-api-input-checks.go @@ -16,11 +16,7 @@ package cmd -import ( - "strings" - - "github.com/skyrings/skyring-common/tools/uuid" -) +import "github.com/skyrings/skyring-common/tools/uuid" // Checks on GetObject arguments, bucket and object. func checkGetObjArgs(bucket, object string) error { @@ -69,7 +65,7 @@ func checkListObjsArgs(bucket, prefix, marker, delimiter string, obj ObjectLayer }) } // Verify if marker has prefix. - if marker != "" && !strings.HasPrefix(marker, prefix) { + if marker != "" && !hasPrefix(marker, prefix) { return traceError(InvalidMarkerPrefixCombination{ Marker: marker, Prefix: prefix, @@ -84,7 +80,7 @@ func checkListMultipartArgs(bucket, prefix, keyMarker, uploadIDMarker, delimiter return err } if uploadIDMarker != "" { - if strings.HasSuffix(keyMarker, slashSeparator) { + if hasSuffix(keyMarker, slashSeparator) { return traceError(InvalidUploadIDKeyCombination{ UploadIDMarker: uploadIDMarker, KeyMarker: keyMarker, diff --git a/cmd/object-api-utils.go b/cmd/object-api-utils.go index 95f63d339..206c0c1a0 100644 --- a/cmd/object-api-utils.go +++ b/cmd/object-api-utils.go @@ -22,6 +22,7 @@ import ( "io" "path" "regexp" + "runtime" "strings" "unicode/utf8" @@ -91,10 +92,10 @@ func IsValidObjectName(object string) bool { if len(object) == 0 { return false } - if strings.HasSuffix(object, slashSeparator) { + if hasSuffix(object, slashSeparator) { return false } - if strings.HasPrefix(object, slashSeparator) { + if hasPrefix(object, slashSeparator) { return false } return IsValidObjectPrefix(object) @@ -159,6 +160,26 @@ func getCompleteMultipartMD5(parts []completePart) (string, error) { return s3MD5, nil } +// Prefix matcher string matches prefix in a platform specific way. +// For example on windows since its case insensitive we are supposed +// to do case insensitive checks. +func hasPrefix(s string, prefix string) bool { + if runtime.GOOS == "windows" { + return strings.HasPrefix(strings.ToLower(s), strings.ToLower(prefix)) + } + return strings.HasPrefix(s, prefix) +} + +// Suffix matcher string matches suffix in a platform specific way. +// For example on windows since its case insensitive we are supposed +// to do case insensitive checks. +func hasSuffix(s string, suffix string) bool { + if runtime.GOOS == "windows" { + return strings.HasSuffix(strings.ToLower(s), strings.ToLower(suffix)) + } + return strings.HasSuffix(s, suffix) +} + // byBucketName is a collection satisfying sort.Interface. type byBucketName []BucketInfo diff --git a/cmd/posix-list-dir-nix.go b/cmd/posix-list-dir-nix.go index 62421abce..1da7eaf76 100644 --- a/cmd/posix-list-dir-nix.go +++ b/cmd/posix-list-dir-nix.go @@ -68,10 +68,6 @@ func parseDirents(dirPath string, buf []byte) (entries []string, err error) { if name == "." || name == ".." { continue } - // Skip special files. - if hasPosixReservedPrefix(name) { - continue - } switch dirent.Type { case syscall.DT_DIR: diff --git a/cmd/posix-list-dir-others.go b/cmd/posix-list-dir-others.go index abd3d965b..dd40faca5 100644 --- a/cmd/posix-list-dir-others.go +++ b/cmd/posix-list-dir-others.go @@ -52,10 +52,6 @@ func readDir(dirPath string) (entries []string, err error) { return nil, err } for _, fi := range fis { - // Skip special files, if found. - if hasPosixReservedPrefix(fi.Name()) { - continue - } // Stat symbolic link and follow to get the final value. if fi.Mode()&os.ModeSymlink == os.ModeSymlink { var st os.FileInfo diff --git a/cmd/posix-list-dir_test.go b/cmd/posix-list-dir_test.go index c709f7ec5..30d85b862 100644 --- a/cmd/posix-list-dir_test.go +++ b/cmd/posix-list-dir_test.go @@ -69,26 +69,6 @@ func setupTestReadDirEmpty(t *testing.T) (testResults []result) { return testResults } -// Test to read empty directory with only reserved names. -func setupTestReadDirReserved(t *testing.T) (testResults []result) { - dir := mustSetupDir(t) - entries := []string{} - // Create a file with reserved name. - for _, reservedName := range posixReservedPrefix { - if err := ioutil.WriteFile(filepath.Join(dir, reservedName), []byte{}, os.ModePerm); err != nil { - // For cleanup, its required to add these entries into test results. - testResults = append(testResults, result{dir, entries}) - t.Fatalf("Unable to create file, %s", err) - } - // entries = append(entries, reservedName) - reserved files are skipped. - } - sort.Strings(entries) - - // Add entries slice for this test directory. - testResults = append(testResults, result{dir, entries}) - return testResults -} - // Test to read non-empty directory with only files. func setupTestReadDirFiles(t *testing.T) (testResults []result) { dir := mustSetupDir(t) @@ -198,8 +178,6 @@ func TestReadDir(t *testing.T) { // Setup and capture test results for empty directory. testResults = append(testResults, setupTestReadDirEmpty(t)...) - // Setup and capture test results for reserved files. - testResults = append(testResults, setupTestReadDirReserved(t)...) // Setup and capture test results for directory with only files. testResults = append(testResults, setupTestReadDirFiles(t)...) // Setup and capture test results for directory with files and directories. diff --git a/cmd/posix-utils_common.go b/cmd/posix-utils_common.go deleted file mode 100644 index ea15b8bca..000000000 --- a/cmd/posix-utils_common.go +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Minio Cloud Storage, (C) 2016 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import "strings" - -// List of reserved words for files, includes old and new ones. -var posixReservedPrefix = []string{ - "$tmpfile", - // Add new reserved words if any used in future. -} - -// hasPosixReservedPrefix - has reserved prefix. -func hasPosixReservedPrefix(name string) (isReserved bool) { - for _, reservedKey := range posixReservedPrefix { - if strings.HasPrefix(name, reservedKey) { - isReserved = true - break - } - } - - return isReserved -} diff --git a/cmd/tree-walk.go b/cmd/tree-walk.go index 8993a96d0..05c78b0cd 100644 --- a/cmd/tree-walk.go +++ b/cmd/tree-walk.go @@ -67,7 +67,7 @@ func filterMatchingPrefix(entries []string, prefixEntry string) []string { if start == end { break } - if strings.HasPrefix(entries[start], prefixEntry) { + if hasPrefix(entries[start], prefixEntry) { break } start++ @@ -76,7 +76,7 @@ func filterMatchingPrefix(entries []string, prefixEntry string) []string { if start == end { break } - if strings.HasPrefix(entries[end-1], prefixEntry) { + if hasPrefix(entries[end-1], prefixEntry) { break } end-- @@ -173,7 +173,7 @@ func doTreeWalk(bucket, prefixDir, entryPrefixMatch, marker string, recursive bo // Skip as the marker would already be listed in the previous listing. continue } - if recursive && !strings.HasSuffix(entry, slashSeparator) { + if recursive && !hasSuffix(entry, slashSeparator) { // We should not skip for recursive listing and if markerDir is a directory // for ex. if marker is "four/five.txt" markerDir will be "four/" which // should not be skipped, instead it will need to be treeWalk()'ed into. @@ -182,7 +182,7 @@ func doTreeWalk(bucket, prefixDir, entryPrefixMatch, marker string, recursive bo continue } } - if recursive && strings.HasSuffix(entry, slashSeparator) { + if recursive && hasSuffix(entry, slashSeparator) { // If the entry is a directory, we will need recurse into it. markerArg := "" if entry == markerDir { diff --git a/cmd/tree-walk_test.go b/cmd/tree-walk_test.go index 939439f2f..9490c6c56 100644 --- a/cmd/tree-walk_test.go +++ b/cmd/tree-walk_test.go @@ -135,7 +135,7 @@ func testTreeWalkPrefix(t *testing.T, listDir listDirFunc, isLeaf isLeafFunc) { // Check if all entries received on the channel match the prefix. for res := range twResultCh { - if !strings.HasPrefix(res.entry, prefix) { + if !hasPrefix(res.entry, prefix) { t.Errorf("Entry %s doesn't match prefix %s", res.entry, prefix) } }