Skip to content

Commit

Permalink
Add IPFS URL+URI parser
Browse files Browse the repository at this point in the history
Accept HTTP gateway URLs and IPFS URIs as arguments
  • Loading branch information
djdv committed Feb 13, 2019
1 parent 796cbc7 commit 9b18e4d
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 14 deletions.
50 changes: 36 additions & 14 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package main

import (
"fmt"
"net/url"
"os"
"os/signal"
gopath "path"
"path/filepath"
"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"
)
Expand Down Expand Up @@ -35,22 +38,21 @@ func main() {
os.Exit(1)
}

outfile := c.String("output")
arg := c.Args().First()
outPath := c.String("output")
iPath, err := parsePath(c.Args().First())
if err != nil {
fmt.Fprintf(os.Stderr, "error: %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()
outfile = segments[len(segments)-1]
if outPath == "" {
trimmed := strings.TrimRight(iPath.String(), "/")
_, outPath = filepath.Split(trimmed)
outPath = filepath.Clean(outPath)
}

var shell fallback.Shell
var err error

if c.String("node") == "fallback" {
shell, err = fallback.NewShell()
Expand All @@ -76,8 +78,8 @@ func main() {
return nil
}

if err := shell.Get(arg, outfile); err != nil {
os.Remove(outfile)
if err := shell.Get(iPath.String(), outPath); err != nil {
os.Remove(outPath)
fmt.Fprintf(os.Stderr, "ipget failed: %s\n", err)
os.Exit(2)
}
Expand Down Expand Up @@ -132,3 +134,23 @@ 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
}
u, err := url.Parse(path)
if err != nil {
return "", fmt.Errorf("%q could not be parsed: %s", path, err)
}

switch proto := u.Scheme; proto {
case "ipfs", "ipld", "ipns":
return ipath.ParsePath(gopath.Join("/", proto, u.Host, u.Path))
case "http", "https":
return ipath.ParsePath(u.Path)
default:
return "", fmt.Errorf("%q is not recognized as an IPFS path")
}
}
25 changes: 25 additions & 0 deletions sharness/t0030-arguments.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh

test_description="test the ipget argument parser"

. ./lib/sharness/sharness.sh

test_expect_success "retrieve a known popular single file with a (HTTP) gateway 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_success "retrieve a known popular single file with browser protocol URI" "
ipget 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-(HTTP)gateway URLS" "
ipget ftp://ipfs.io/ipfs/QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF/cat.gif
"

test_done

0 comments on commit 9b18e4d

Please sign in to comment.