Skip to content

Commit

Permalink
Fix offline gateway directory logic
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
  • Loading branch information
magik6k committed Jan 4, 2019
1 parent 041c46e commit 6cee21d
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 37 deletions.
3 changes: 1 addition & 2 deletions core/coreapi/coreapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,8 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e
subApi.recordValidator = nil

subApi.exchange = offlinexch.Exchange(subApi.blockstore)
subApi.blocks = bserv.New(api.blockstore, subApi.exchange)
subApi.blocks = bserv.New(subApi.blockstore, subApi.exchange)
subApi.dag = dag.NewDAGService(subApi.blocks)

}

return subApi, nil
Expand Down
9 changes: 7 additions & 2 deletions core/coreapi/interface/path.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package iface

import (
"gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
ipfspath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path"

cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
)

//TODO: merge with ipfspath so we don't depend on it
Expand Down Expand Up @@ -106,6 +105,12 @@ type resolvedPath struct {
remainder string
}

// Join appends provided segments to the base path
func Join(base Path, a ...string) Path {
s := ipfspath.Join(append([]string{base.String()}, a...))
return &path{path: ipfspath.FromString(s)}
}

// IpfsPath creates new /ipfs path from the provided CID
func IpfsPath(c cid.Cid) ResolvedPath {
return &resolvedPath{
Expand Down
12 changes: 12 additions & 0 deletions core/coreapi/interface/tests/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func (tp *provider) TestPath(t *testing.T) {
t.Run("TestEmptyPathRemainder", tp.TestEmptyPathRemainder)
t.Run("TestInvalidPathRemainder", tp.TestInvalidPathRemainder)
t.Run("TestPathRoot", tp.TestPathRoot)
t.Run("TestPathJoin", tp.TestPathJoin)
}

func (tp *provider) TestMutablePath(t *testing.T) {
Expand Down Expand Up @@ -165,3 +166,14 @@ func (tp *provider) TestPathRoot(t *testing.T) {
t.Error("unexpected path cid")
}
}

func (tp *provider) TestPathJoin(t *testing.T) {
p1, err := coreiface.ParsePath("/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz")
if err != nil {
t.Error(err)
}

if coreiface.Join(p1, "foo").String() != "/ipfs/QmYNmQKp6SuaVrpgWRsPTgCQCnpxUYGq76YEKBXuj2N4H6/bar/baz/foo" {
t.Error("unexpected path")
}
}
7 changes: 6 additions & 1 deletion core/coreapi/unixfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,12 @@ func (d *ufsDirectory) Entries() files.DirIterator {
}

func (d *ufsDirectory) Size() (int64, error) {
return 0, files.ErrNotSupported
n, err := d.dir.GetNode()
if err != nil {
return 0, err
}
s, err := n.Size()
return int64(s), err
}

type ufsFile struct {
Expand Down
2 changes: 1 addition & 1 deletion core/corehttp/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package corehttp

import (
"fmt"
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
"net"
"net/http"

version "github.com/ipfs/go-ipfs"
core "github.com/ipfs/go-ipfs/core"
coreapi "github.com/ipfs/go-ipfs/core/coreapi"
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"

id "gx/ipfs/QmRBaUEQEeFWywfrZJ64QgsmvcqgLSK3VbvGMR2NM2Edpf/go-libp2p/p2p/protocol/identify"
)
Expand Down
49 changes: 22 additions & 27 deletions core/corehttp/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"net/http"
"net/url"
"os"
gopath "path"
"runtime/debug"
"strings"
Expand All @@ -26,7 +25,6 @@ import (
"gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path/resolver"
ft "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs"
"gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs/importer"
uio "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs/io"
ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag"
"gx/ipfs/QmekxXDhCxCJRNuzmHreuaT3BsuJcsjcXWNrtV9C8DRHtd/go-multibase"
Expand Down Expand Up @@ -254,22 +252,14 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
}
i.serveFile(w, r, name, modtime, f)
return

}

nd, err := i.api.ResolveNode(ctx, resolvedPath)
if err != nil {
internalWebError(w, err)
return
}

dirr, err := uio.NewDirectoryFromNode(i.node.DAG, nd)
if err != nil {
internalWebError(w, err)
dir, ok := dr.(files.Directory)
if !ok {
internalWebError(w, fmt.Errorf("unsupported file type"))
return
}

ixnd, err := dirr.Find(ctx, "index.html")
idx, err := i.api.Unixfs().Get(ctx, coreiface.Join(resolvedPath, "index.html"))
switch {
case err == nil:
dirwithoutslash := urlPath[len(urlPath)-1] != '/'
Expand All @@ -280,14 +270,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
return
}

dr, err := i.api.Unixfs().Get(ctx, coreiface.IpfsPath(ixnd.Cid()))
if err != nil {
internalWebError(w, err)
return
}
defer dr.Close()

f, ok := dr.(files.File)
f, ok := idx.(files.File)
if !ok {
internalWebError(w, files.ErrNotReader)
return
Expand All @@ -297,9 +280,11 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
http.ServeContent(w, r, "index.html", modtime, f)
return
default:
if _, ok := err.(resolver.ErrNoLink); ok {
break
}
internalWebError(w, err)
return
case os.IsNotExist(err):
}

if r.Method == "HEAD" {
Expand All @@ -308,12 +293,22 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr

// storage for directory listing
var dirListing []directoryItem
dirr.ForEachLink(ctx, func(link *ipld.Link) error {
dirit := dir.Entries()
for dirit.Next() {
// See comment above where originalUrlPath is declared.
di := directoryItem{humanize.Bytes(link.Size), link.Name, gopath.Join(originalUrlPath, link.Name)}
s, err := dirit.Node().Size()
if err != nil {
internalWebError(w, err)
return
}

di := directoryItem{humanize.Bytes(uint64(s)), dirit.Name(), gopath.Join(originalUrlPath, dirit.Name())}
dirListing = append(dirListing, di)
return nil
})
}
if dirit.Err() != nil {
internalWebError(w, dirit.Err())
return
}

// construct the correct back link
// https://github.com/ipfs/go-ipfs/issues/1365
Expand Down
8 changes: 4 additions & 4 deletions test/sharness/t0110-gateway.sh
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,14 @@ test_expect_success "start ipfs nodes" '
'

test_expect_success "try fetching not present key from node 0" '
echo "hi" | ipfsi 1 add -Q > hi.hash &&
test_expect_code 22 curl -f "http://127.0.0.1:$GWPORT/ipfs/$(cat hi.hash)"
echo "foo" | ipfsi 1 add -Q > foo.hash &&
test_expect_code 22 curl -f "http://127.0.0.1:$GWPORT/ipfs/$(cat foo.hash)"
'

test_expect_success "try fetching present key from from node 0" '
echo "hi" | ipfsi 0 add -Q > hi.hash &&
echo "bar" | ipfsi 0 add -Q > bar.hash &&
PORT1=$(ipfs config Addresses.Gateway | cut -d/ -f 5) &&
curl -f "http://127.0.0.1:$GWPORT/ipfs/$(cat hi.hash)"
curl -f "http://127.0.0.1:$GWPORT/ipfs/$(cat bar.hash)"
'

test_expect_success "stop testbed" '
Expand Down

0 comments on commit 6cee21d

Please sign in to comment.