From eb0b41ccb03ee59ed78b0ddd9b50300fbe80e365 Mon Sep 17 00:00:00 2001 From: Dominic Della Valle Date: Tue, 13 Feb 2018 11:28:00 -0500 Subject: [PATCH] Add gateway URL parser Allows HTTP gateway urls as arguments --- main.go | 33 +++++++++++++++++++++++---------- sharness/t0030-arguments.sh | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 10 deletions(-) create mode 100755 sharness/t0030-arguments.sh diff --git a/main.go b/main.go index c094b95..1887617 100644 --- a/main.go +++ b/main.go @@ -4,10 +4,11 @@ import ( "fmt" "os" "os/signal" + "regexp" "strings" "syscall" - path "gx/ipfs/QmT3rzed1ppXefourpmoZ7tyVQfsGPQZ1pHDngLmCvXxd3/go-path" + ipath "gx/ipfs/QmT3rzed1ppXefourpmoZ7tyVQfsGPQZ1pHDngLmCvXxd3/go-path" fallback "gx/ipfs/QmaWDhoQaV6cDyy6NSKFgPaUAGRtb4SMiLpaDYEsxP7X8P/fallback-ipfs-shell" cli "gx/ipfs/Qmc1AtgBdoUHP8oYSqU81NRYdzohmF45t5XNwVMvhCxsBA/cli" ) @@ -36,21 +37,19 @@ func main() { } outfile := c.String("output") - arg := c.Args().First() + inPath, err := parsePath(c.Args().First()) + if err != nil { + fmt.Fprintf(os.Stderr, "Argument parse failure: %s\n", err) + os.Exit(1) + } // Use the final segment of the object's path if no path was given. if outfile == "" { - ipfsPath, err := path.ParsePath(arg) - if err != nil { - fmt.Fprintf(os.Stderr, "ParsePath failure: %s\n", err) - os.Exit(1) - } - segments := ipfsPath.Segments() + segments := inPath.Segments() outfile = segments[len(segments)-1] } var shell fallback.Shell - var err error if c.String("node") == "fallback" { shell, err = fallback.NewShell() @@ -76,7 +75,7 @@ func main() { return nil } - if err := shell.Get(arg, outfile); err != nil { + if err := shell.Get(inPath.String(), outfile); err != nil { os.Remove(outfile) fmt.Fprintf(os.Stderr, "ipget failed: %s\n", err) os.Exit(2) @@ -132,3 +131,17 @@ func movePostfixOptions(args []string) []string { // append extracted arguments to the real args return append(args, the_args...) } + +func parsePath(path string) (ipath.Path, error) { + ipfsPath, err := ipath.ParsePath(path) + if err == nil { // valid canonical path + return ipfsPath, nil + } + // allow HTTP gateway URLs as input as well + matches := regexp.MustCompile(`^https?.*(/(ipfs|ipns|ipld)/.+)$`).FindStringSubmatch(path) + if len(matches) < 1 { + return "", fmt.Errorf("%q does not appear to be a valid IPFS path or HTTP gateway URL", path) + } + + return ipath.ParsePath(matches[1]) +} diff --git a/sharness/t0030-arguments.sh b/sharness/t0030-arguments.sh new file mode 100755 index 0000000..33f5841 --- /dev/null +++ b/sharness/t0030-arguments.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +test_description="test the ipget argument parser" + +. ./lib/sharness/sharness.sh + +test_expect_success "retrieve a known popular single file with a gateway HTTP URL" " + ipget http://ipfs.io/ipfs/QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF/cat.gif && + echo 'c5ea0d6cacf1e54635685803ec4edbe0d4fe8465' > expected && + shasum cat.gif | cut -d ' ' -f 1 > actual && + diff expected actual +" + +test_expect_failure "don't allow non-gateway URLS" " + ipget ftp://ipfs.io/ipfs/QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF/cat.gif +" + +test_expect_success "retrieve a directory" " + ipget --node=spawn QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF && + ls QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF > /dev/null && + ls QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF/cat.gif > /dev/null +" + +test_done