Fix all remaining windows path issues.

master
Harshavardhana 9 years ago
parent 8978c19db6
commit 1f66f4869b
  1. 4
      Makefile
  2. 10
      pkg/fs/api_suite_windows_test.go
  3. 29
      pkg/fs/fs-bucket.go
  4. 14
      pkg/fs/fs-common.go
  5. 4
      pkg/fs/fs-object.go

@ -35,8 +35,8 @@ lint:
cyclo: cyclo:
@echo "Running $@:" @echo "Running $@:"
@GO15VENDOREXPERIMENT=1 gocyclo -over 60 *.go @GO15VENDOREXPERIMENT=1 gocyclo -over 65 *.go
@GO15VENDOREXPERIMENT=1 gocyclo -over 60 pkg @GO15VENDOREXPERIMENT=1 gocyclo -over 65 pkg
build: getdeps verifiers build: getdeps verifiers
@echo "Installing minio:" #@GO15VENDOREXPERIMENT=1 deadcode @echo "Installing minio:" #@GO15VENDOREXPERIMENT=1 deadcode

@ -228,13 +228,13 @@ func testPaging(c *check.C, create func() Filesystem) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
var prefixes []string var prefixes []string
resources.CommonPrefixes = prefixes // allocate new everytime resources.CommonPrefixes = prefixes // allocate new everytime
resources.Delimiter = "\\" resources.Delimiter = "/"
resources.Prefix = "this\\is\\" resources.Prefix = "this/is/"
resources.Maxkeys = 10 resources.Maxkeys = 10
objects, resources, err = fs.ListObjects("bucket", resources) objects, resources, err = fs.ListObjects("bucket", resources)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(len(objects), check.Equals, 1) c.Assert(len(objects), check.Equals, 1)
c.Assert(resources.CommonPrefixes[0], check.Equals, "this\\is\\also\\") c.Assert(resources.CommonPrefixes[0], check.Equals, "this/is/also/")
} }
time.Sleep(time.Second) time.Sleep(time.Second)
@ -242,7 +242,7 @@ func testPaging(c *check.C, create func() Filesystem) {
{ {
var prefixes []string var prefixes []string
resources.CommonPrefixes = prefixes // allocate new everytime resources.CommonPrefixes = prefixes // allocate new everytime
resources.Delimiter = "\\" resources.Delimiter = "/"
resources.Prefix = "" resources.Prefix = ""
resources.Maxkeys = 1000 resources.Maxkeys = 1000
objects, resources, err = fs.ListObjects("bucket", resources) objects, resources, err = fs.ListObjects("bucket", resources)
@ -252,7 +252,7 @@ func testPaging(c *check.C, create func() Filesystem) {
c.Assert(objects[2].Object, check.Equals, "obj0") c.Assert(objects[2].Object, check.Equals, "obj0")
c.Assert(objects[3].Object, check.Equals, "obj1") c.Assert(objects[3].Object, check.Equals, "obj1")
c.Assert(objects[4].Object, check.Equals, "obj10") c.Assert(objects[4].Object, check.Equals, "obj10")
c.Assert(resources.CommonPrefixes[0], check.Equals, "this\\") c.Assert(resources.CommonPrefixes[0], check.Equals, "this/")
} }
// check results with Marker // check results with Marker

@ -219,11 +219,17 @@ func (fs Filesystem) ListObjects(bucket string, resources BucketResourcesMetadat
} }
p.root = rootPrefix p.root = rootPrefix
/// automatically treat "/" delimiter as "\\" delimiter on windows due to its path constraints. /// automatically treat incoming "/" as "\\" on windows due to its path constraints.
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
resources.Prefix = strings.Replace(resources.Prefix, "/", string(os.PathSeparator), -1) if resources.Prefix != "" {
resources.Delimiter = strings.Replace(resources.Delimiter, "/", string(os.PathSeparator), -1) resources.Prefix = strings.Replace(resources.Prefix, "/", string(os.PathSeparator), -1)
resources.Marker = strings.Replace(resources.Marker, "/", string(os.PathSeparator), -1) }
if resources.Delimiter != "" {
resources.Delimiter = strings.Replace(resources.Delimiter, "/", string(os.PathSeparator), -1)
}
if resources.Marker != "" {
resources.Marker = strings.Replace(resources.Marker, "/", string(os.PathSeparator), -1)
}
} }
// if delimiter is supplied and not prefix then we are the very top level, list everything and move on. // if delimiter is supplied and not prefix then we are the very top level, list everything and move on.
@ -318,7 +324,11 @@ func (fs Filesystem) ListObjects(bucket string, resources BucketResourcesMetadat
// has the prefix if it does not skip the directory. // has the prefix if it does not skip the directory.
if fl.Mode().IsDir() { if fl.Mode().IsDir() {
if resources.Prefix != "" { if resources.Prefix != "" {
if !strings.HasPrefix(fp, filepath.Join(p.root, resources.Prefix)) { // Skip the directory on following situations
// - when prefix is part of file pointer along with the root path
// - when file pointer is part of the prefix along with root path
if !strings.HasPrefix(fp, filepath.Join(p.root, resources.Prefix)) &&
!strings.HasPrefix(filepath.Join(p.root, resources.Prefix), fp) {
return ErrSkipDir return ErrSkipDir
} }
} }
@ -328,6 +338,7 @@ func (fs Filesystem) ListObjects(bucket string, resources BucketResourcesMetadat
if fl.Mode().IsDir() { if fl.Mode().IsDir() {
if resources.Marker != "" { if resources.Marker != "" {
if realFp != "" { if realFp != "" {
// For windows split with its own os.PathSeparator
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
if realFp < strings.Split(resources.Marker, string(os.PathSeparator))[0] { if realFp < strings.Split(resources.Marker, string(os.PathSeparator))[0] {
return ErrSkipDir return ErrSkipDir
@ -427,10 +438,18 @@ func (fs Filesystem) ListObjects(bucket string, resources BucketResourcesMetadat
if err != nil { if err != nil {
return nil, resources, err.Trace() return nil, resources, err.Trace()
} }
// If windows replace all the incoming paths to API compatible paths
if runtime.GOOS == "windows" {
metadata.Object = sanitizeWindowsPath(metadata.Object)
}
if metadata.Bucket != "" { if metadata.Bucket != "" {
metadataList = append(metadataList, metadata) metadataList = append(metadataList, metadata)
} }
} }
} }
// Sanitize common prefixes back into API compatible paths
if runtime.GOOS == "windows" {
resources.CommonPrefixes = sanitizeWindowsPaths(resources.CommonPrefixes...)
}
return metadataList, resources, nil return metadataList, resources, nil
} }

@ -31,6 +31,20 @@ type Metadata struct {
ContentType string ContentType string
} }
// sanitizeWindowsPath - sanitize a path
func sanitizeWindowsPath(path string) string {
return strings.Replace(path, "\\", "/", -1)
}
// sanitizeWindowsPaths - sanitize some windows paths
func sanitizeWindowsPaths(paths ...string) []string {
var results []string
for _, path := range paths {
results = append(results, sanitizeWindowsPath(path))
}
return results
}
// sortUnique sort a slice in lexical order, removing duplicate elements // sortUnique sort a slice in lexical order, removing duplicate elements
func sortUnique(objects []string) []string { func sortUnique(objects []string) []string {
results := []string{} results := []string{}

@ -118,6 +118,7 @@ func getMetadata(rootPath, bucket, object string) (ObjectMetadata, *probe.Error)
// Do not use filepath.Join() since filepath.Join strips off any object names with '/', use them as is // Do not use filepath.Join() since filepath.Join strips off any object names with '/', use them as is
// in a static manner so that we can send a proper 'ObjectNotFound' reply back upon os.Stat() // in a static manner so that we can send a proper 'ObjectNotFound' reply back upon os.Stat()
var objectPath string var objectPath string
// For windows use its special os.PathSeparator == "\\"
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
objectPath = rootPath + string(os.PathSeparator) + bucket + string(os.PathSeparator) + object objectPath = rootPath + string(os.PathSeparator) + bucket + string(os.PathSeparator) + object
} else { } else {
@ -131,6 +132,9 @@ func getMetadata(rootPath, bucket, object string) (ObjectMetadata, *probe.Error)
return ObjectMetadata{}, probe.NewError(err) return ObjectMetadata{}, probe.NewError(err)
} }
contentType := "application/octet-stream" contentType := "application/octet-stream"
if runtime.GOOS == "windows" {
object = sanitizeWindowsPath(object)
}
metadata := ObjectMetadata{ metadata := ObjectMetadata{
Bucket: bucket, Bucket: bucket,
Object: object, Object: object,

Loading…
Cancel
Save