1
0
mirror of https://github.com/minio/mc.git synced 2025-11-12 01:02:26 +03:00

Always make sure to verify argument validation in checkSyntax**.

Cleanup share-upload.go to be aware of different argument validation.
This commit is contained in:
Harshavardhana
2015-10-10 13:05:14 -07:00
parent f730083872
commit c4b9891c6e
9 changed files with 80 additions and 31 deletions

1
ls.go
View File

@@ -124,6 +124,7 @@ func doList(clnt client.Client, recursive, multipleArgs bool) *probe.Error {
if os.IsNotExist(contentCh.Err.ToGoError()) || os.IsPermission(contentCh.Err.ToGoError()) { if os.IsNotExist(contentCh.Err.ToGoError()) || os.IsPermission(contentCh.Err.ToGoError()) {
if contentCh.Content != nil { if contentCh.Content != nil {
if contentCh.Content.Type.IsDir() && (contentCh.Content.Type&os.ModeSymlink == os.ModeSymlink) { if contentCh.Content.Type.IsDir() && (contentCh.Content.Type&os.ModeSymlink == os.ModeSymlink) {
errorIf(contentCh.Err.Trace(), "Unable to list broken folder link.")
continue continue
} }
} }

View File

@@ -62,7 +62,7 @@ func (f *fsClient) fsStat() (os.FileInfo, *probe.Error) {
// Resolve symlinks // Resolve symlinks
fpath, err := filepath.EvalSymlinks(fpath) fpath, err := filepath.EvalSymlinks(fpath)
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// On windows there are directory symlinks // On windows there are folder symlinks
// which are called junction files which // which are called junction files which
// carry special meaning on windows // carry special meaning on windows
// - which cannot be accessed with regular operations // - which cannot be accessed with regular operations
@@ -252,7 +252,7 @@ func (f *fsClient) listInRoutine(contentCh chan client.ContentOnChannel) {
if fi.Mode()&os.ModeSymlink == os.ModeSymlink { if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
fi, err = os.Stat(filepath.Join(dir.Name(), fi.Name())) fi, err = os.Stat(filepath.Join(dir.Name(), fi.Name()))
if os.IsPermission(err) { if os.IsPermission(err) {
// On windows there are directory symlinks // On windows there are folder symlinks
// which are called junction files which // which are called junction files which
// carry special meaning on windows // carry special meaning on windows
// - which cannot be accessed with regular operations // - which cannot be accessed with regular operations
@@ -348,7 +348,7 @@ func (f *fsClient) listRecursiveInRoutine(contentCh chan client.ContentOnChannel
} }
if os.IsPermission(err) { if os.IsPermission(err) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// On windows there are directory symlinks // On windows there are folder symlinks
// which are called junction files which // which are called junction files which
// carry special meaning on windows // carry special meaning on windows
// - which cannot be accessed with regular operations // - which cannot be accessed with regular operations
@@ -384,7 +384,7 @@ func (f *fsClient) listRecursiveInRoutine(contentCh chan client.ContentOnChannel
if err != nil { if err != nil {
if os.IsPermission(err) { if os.IsPermission(err) {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// On windows there are directory symlinks // On windows there are folder symlinks
// which are called junction files which // which are called junction files which
// carry special meaning on windows // carry special meaning on windows
// - which cannot be accessed with regular operations // - which cannot be accessed with regular operations

View File

@@ -89,15 +89,24 @@ func (c *s3Client) ShareDownload(expires time.Duration) (string, *probe.Error) {
func (c *s3Client) ShareUpload(recursive bool, expires time.Duration, contentType string) (map[string]string, *probe.Error) { func (c *s3Client) ShareUpload(recursive bool, expires time.Duration, contentType string) (map[string]string, *probe.Error) {
bucket, object := c.url2BucketAndObject() bucket, object := c.url2BucketAndObject()
p := minio.NewPostPolicy() p := minio.NewPostPolicy()
p.SetExpires(time.Now().UTC().Add(expires)) if err := p.SetExpires(time.Now().UTC().Add(expires)); err != nil {
if len(contentType) > 0 { return nil, probe.NewError(err)
}
if strings.TrimSpace(contentType) != "" || contentType != "" {
// No need to check for errors here, we have trimmed off the spaces
p.SetContentType(contentType) p.SetContentType(contentType)
} }
p.SetBucket(bucket) if err := p.SetBucket(bucket); err != nil {
return nil, probe.NewError(err)
}
if recursive { if recursive {
p.SetKeyStartsWith(object) if err := p.SetKeyStartsWith(object); err != nil {
return nil, probe.NewError(err)
}
} else { } else {
p.SetKey(object) if err := p.SetKey(object); err != nil {
return nil, probe.NewError(err)
}
} }
m, err := c.api.PresignedPostPolicy(p) m, err := c.api.PresignedPostPolicy(p)
return m, probe.NewError(err) return m, probe.NewError(err)

View File

@@ -89,15 +89,24 @@ func (c *s3Client) ShareDownload(expires time.Duration) (string, *probe.Error) {
func (c *s3Client) ShareUpload(recursive bool, expires time.Duration, contentType string) (map[string]string, *probe.Error) { func (c *s3Client) ShareUpload(recursive bool, expires time.Duration, contentType string) (map[string]string, *probe.Error) {
bucket, object := c.url2BucketAndObject() bucket, object := c.url2BucketAndObject()
p := minio.NewPostPolicy() p := minio.NewPostPolicy()
p.SetExpires(time.Now().UTC().Add(expires)) if err := p.SetExpires(time.Now().UTC().Add(expires)); err != nil {
if len(contentType) > 0 { return nil, probe.NewError(err)
}
if strings.TrimSpace(contentType) != "" || contentType != "" {
// No need to verify for error here, since we have stripped out spaces
p.SetContentType(contentType) p.SetContentType(contentType)
} }
p.SetBucket(bucket) if err := p.SetBucket(bucket); err != nil {
return nil, probe.NewError(err)
}
if recursive { if recursive {
p.SetKeyStartsWith(object) if err := p.SetKeyStartsWith(object); err != nil {
return nil, probe.NewError(err)
}
} else { } else {
p.SetKey(object) if err := p.SetKey(object); err != nil {
return nil, probe.NewError(err)
}
} }
m, err := c.api.PresignedPostPolicy(p) m, err := c.api.PresignedPostPolicy(p)
return m, probe.NewError(err) return m, probe.NewError(err)

View File

@@ -192,7 +192,7 @@ func mainSession(ctx *cli.Context) {
setSessionPalette(ctx.GlobalString("colors")) setSessionPalette(ctx.GlobalString("colors"))
if !isSessionDirExists() { if !isSessionDirExists() {
fatalIf(createSessionDir().Trace(), "Unable to create session directory.") fatalIf(createSessionDir().Trace(), "Unable to create session folder.")
} }
switch strings.TrimSpace(ctx.Args().First()) { switch strings.TrimSpace(ctx.Args().First()) {
@@ -219,7 +219,7 @@ func mainSession(ctx *cli.Context) {
if s.Header.RootPath != "" { if s.Header.RootPath != "" {
// chdir to RootPath // chdir to RootPath
e = os.Chdir(s.Header.RootPath) e = os.Chdir(s.Header.RootPath)
fatalIf(probe.NewError(e), "Unable to change directory to root path while resuming session.") fatalIf(probe.NewError(e), "Unable to change our folder to root path while resuming session.")
} }
sessionExecute(s) sessionExecute(s)
err = s.Close() err = s.Close()
@@ -230,7 +230,7 @@ func mainSession(ctx *cli.Context) {
// chdir back to saved path // chdir back to saved path
e = os.Chdir(savedCwd) e = os.Chdir(savedCwd)
fatalIf(probe.NewError(e), "Unable to change directory to saved path "+savedCwd+".") fatalIf(probe.NewError(e), "Unable to change our folder to saved path "+savedCwd+".")
// purge a requested pending session, if "all" purge everything // purge a requested pending session, if "all" purge everything
case "clear": case "clear":

View File

@@ -84,7 +84,7 @@ func mainShareDownload(ctx *cli.Context) {
// if recursive strip off the "..." // if recursive strip off the "..."
err := doShareDownloadURL(stripRecursiveURL(targetURL), isURLRecursive(targetURL), expires) err := doShareDownloadURL(stripRecursiveURL(targetURL), isURLRecursive(targetURL), expires)
fatalIf(err.Trace(targetURL), "Unable to generate URL for sharing.") fatalIf(err.Trace(targetURL), "Unable to generate URL for download.")
return return
} }

View File

@@ -59,6 +59,13 @@ func checkShareUploadSyntax(ctx *cli.Context) {
if len(args) > 3 { if len(args) > 3 {
cli.ShowCommandHelpAndExit(ctx, "upload", 1) // last argument is exit code cli.ShowCommandHelpAndExit(ctx, "upload", 1) // last argument is exit code
} }
url := stripRecursiveURL(strings.TrimSpace(args.Get(0)))
if !isObjectKeyPresent(url) {
fatalIf(errDummy().Trace(), fmt.Sprintf("Upload location needs object key %s.", strings.TrimSpace(args.Get(0))))
}
if strings.HasSuffix(strings.TrimSpace(args.Get(0)), "/") {
fatalIf(errDummy().Trace(), fmt.Sprintf("Upload location cannot end with /. Did you mean %s.", url+recursiveSeparator))
}
} }
func mainShareUpload(ctx *cli.Context) { func mainShareUpload(ctx *cli.Context) {
@@ -70,23 +77,19 @@ func mainShareUpload(ctx *cli.Context) {
args := ctx.Args() args := ctx.Args()
config := mustGetMcConfig() config := mustGetMcConfig()
url := args.Get(0) if strings.TrimSpace(args.Get(1)) == "" {
if strings.HasSuffix(url, "/") {
fatalIf(errDummy().Trace(), fmt.Sprintf("Upload location can not end with '/'. Did you mean %s%s", url, recursiveSeparator))
}
if len(args.Get(1)) == 0 {
expires = time.Duration(604800) * time.Second expires = time.Duration(604800) * time.Second
} else { } else {
expires, err = time.ParseDuration(args.Get(1)) expires, err = time.ParseDuration(strings.TrimSpace(args.Get(1)))
if err != nil { if err != nil {
fatalIf(probe.NewError(err), "Unable to parse time argument.") fatalIf(probe.NewError(err), "Unable to parse time argument.")
} }
} }
contentType := args.Get(2) contentType := strings.TrimSpace(args.Get(2))
targetURL := getAliasURL(url, config.Aliases) targetURL := getAliasURL(strings.TrimSpace(args.Get(0)), config.Aliases)
e := doShareUploadURL(stripRecursiveURL(targetURL), isURLRecursive(targetURL), expires, contentType) e := doShareUploadURL(stripRecursiveURL(targetURL), isURLRecursive(targetURL), expires, contentType)
fatalIf(e.Trace(targetURL), "Unable to generate URL for sharing.") fatalIf(e.Trace(targetURL), "Unable to generate URL for upload.")
} }
// doShareURL share files from target // doShareURL share files from target

View File

@@ -33,9 +33,9 @@ import (
func shareDataDirSetup() { func shareDataDirSetup() {
if !isSharedURLsDataDirExists() { if !isSharedURLsDataDirExists() {
shareDir, err := getSharedURLsDataDir() shareDir, err := getSharedURLsDataDir()
fatalIf(err.Trace(), "Unable to get shared URL data directory") fatalIf(err.Trace(), "Unable to get shared URL data folder.")
fatalIf(createSharedURLsDataDir().Trace(), "Unable to create shared URL data directory "+shareDir+".") fatalIf(createSharedURLsDataDir().Trace(), "Unable to create shared URL data folder "+shareDir+".")
} }
if !isSharedURLsDataFileExists() { if !isSharedURLsDataFileExists() {
shareFile, err := getSharedURLsDataFile() shareFile, err := getSharedURLsDataFile()
@@ -217,6 +217,32 @@ func path2Bucket(u *client.URL) (bucketName string) {
return bucketName return bucketName
} }
// this code is necessary since, share only operates on cloud storage URLs not filesystem
func isObjectKeyPresent(url string) bool {
u := client.NewURL(url)
path := u.Path
match, _ := filepath.Match("*.s3*.amazonaws.com", u.Host)
switch {
case match == true:
hostSplits := strings.SplitN(u.Host, ".", 2)
path = string(u.Separator) + hostSplits[0] + u.Path
}
pathSplits := strings.SplitN(path, "?", 2)
splits := strings.SplitN(pathSplits[0], string(u.Separator), 3)
switch len(splits) {
case 0, 1:
return false
case 2:
return false
case 3:
if splits[2] == "" {
return false
}
return true
}
return false
}
func setSharePalette(style string) { func setSharePalette(style string) {
console.SetCustomPalette(map[string]*color.Color{ console.SetCustomPalette(map[string]*color.Color{
"Share": color.New(color.FgGreen, color.Bold), "Share": color.New(color.FgGreen, color.Bold),

View File

@@ -81,17 +81,18 @@ func (sl *sortedList) Create(clnt client.Client, id string) *probe.Error {
switch err := content.Err.ToGoError().(type) { switch err := content.Err.ToGoError().(type) {
case client.BrokenSymlink: case client.BrokenSymlink:
// FIXME: send the error to caller using channel // FIXME: send the error to caller using channel
errorIf(content.Err.Trace(), fmt.Sprintf("Skipping broken Symlink %s.", err.Path)) errorIf(content.Err.Trace(), fmt.Sprintf("Skipping broken symlink %s.", err.Path))
continue continue
case client.TooManyLevelsSymlink: case client.TooManyLevelsSymlink:
// FIXME: send the error to caller using channel // FIXME: send the error to caller using channel
errorIf(content.Err.Trace(), fmt.Sprintf("Skipping too many levels Symlink %s.", err.Path)) errorIf(content.Err.Trace(), fmt.Sprintf("Skipping too many levels symlink %s.", err.Path))
continue continue
} }
if os.IsNotExist(content.Err.ToGoError()) || os.IsPermission(content.Err.ToGoError()) { if os.IsNotExist(content.Err.ToGoError()) || os.IsPermission(content.Err.ToGoError()) {
// FIXME: abstract this at fs.go layer // FIXME: abstract this at fs.go layer
if content.Content != nil { if content.Content != nil {
if content.Content.Type.IsDir() && (content.Content.Type&os.ModeSymlink == os.ModeSymlink) { if content.Content.Type.IsDir() && (content.Content.Type&os.ModeSymlink == os.ModeSymlink) {
errorIf(content.Err.Trace(), fmt.Sprintf("Skipping broken folder symlink %s.", content.Content.Name))
continue continue
} }
errorIf(content.Err.Trace(), fmt.Sprintf("Skipping %s.", content.Content.Name)) errorIf(content.Err.Trace(), fmt.Sprintf("Skipping %s.", content.Content.Name))