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:
1
ls.go
1
ls.go
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
30
share.go
30
share.go
@@ -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),
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user