diff --git a/cli/parse.go b/cli/parse.go index e8cfdb3b..14823a63 100644 --- a/cli/parse.go +++ b/cli/parse.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "net/url" "os" "path" "path/filepath" @@ -269,6 +270,8 @@ func parseArgs(req *cmds.Request, root *cmds.Command, stdin *os.File) error { if err != nil { return err } + } else if u := isURL(fpath); u != nil { + file = files.NewWebFile(u) } else { fpath = filepath.ToSlash(filepath.Clean(fpath)) derefArgs, _ := req.Options[cmds.DerefLong].(bool) @@ -338,6 +341,23 @@ func parseArgs(req *cmds.Request, root *cmds.Command, stdin *os.File) error { return nil } +// isURL returns a url.URL for valid http:// and https:// URLs, otherwise it returns nil. +func isURL(path string) *url.URL { + u, err := url.Parse(path) + if err != nil { + return nil + } + if u.Host == "" { + return nil + } + switch u.Scheme { + default: + return nil + case "http", "https": + return u + } +} + func splitkv(opt string) (k, v string, ok bool) { split := strings.SplitN(opt, "=", 2) if len(split) == 2 { diff --git a/cli/parse_test.go b/cli/parse_test.go index ddb8c836..7ac1a548 100644 --- a/cli/parse_test.go +++ b/cli/parse_test.go @@ -513,3 +513,24 @@ func TestBodyArgs(t *testing.T) { } } } + +func Test_isURL(t *testing.T) { + for _, u := range []string{ + "http://www.example.com", + "https://www.example.com", + } { + if isURL(u) == nil { + t.Errorf("expected url: %s", u) + } + } + + for _, u := range []string{ + "adir/afile", + "http:/ /afile", + "http:/a/file", + } { + if isURL(u) != nil { + t.Errorf("expected non-url: %s", u) + } + } +}