Skip to content

Commit

Permalink
wip: car gateway example
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Jan 31, 2023
1 parent 43deb6b commit 8f29e0a
Show file tree
Hide file tree
Showing 8 changed files with 1,922 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/gateway/car-file-gateway/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.car
88 changes: 88 additions & 0 deletions examples/gateway/car-file-gateway/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package main

import (
"context"
"fmt"
"io"
gopath "path"

"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid"
bsfetcher "github.com/ipfs/go-fetcher/impl/blockservice"
blockstore "github.com/ipfs/go-ipfs-blockstore"
offline "github.com/ipfs/go-ipfs-exchange-offline"
ipld "github.com/ipfs/go-ipld-format"
"github.com/ipfs/go-merkledag"
ipfspath "github.com/ipfs/go-path"
ipfspathresolver "github.com/ipfs/go-path/resolver"
"github.com/ipfs/go-unixfsnode"
"github.com/ipfs/interface-go-ipfs-core/path"
carblockstore "github.com/ipld/go-car/v2/blockstore"
)

type carGateway struct {
bs blockstore.Blockstore
bsrv blockservice.BlockService
dsrv ipld.DAGService
}

func newCarGateway(car io.ReaderAt) (*carGateway, error) {
bs, err := carblockstore.NewReadOnly(car, nil)
if err != nil {
return nil, err
}

bsrv := blockservice.New(bs, offline.Exchange(bs))
dsrv := merkledag.NewDAGService(bsrv)

return &carGateway{
bs: bs,
bsrv: bsrv,
dsrv: dsrv,
}, nil
}

func (api *carGateway) resolvePath(ctx context.Context, pth path.Path) (path.Resolved, error) {
if _, ok := pth.(path.Resolved); ok {
return pth.(path.Resolved), nil
}

if err := pth.IsValid(); err != nil {
return nil, fmt.Errorf("path: %w", err)
}

if pth.Namespace() != "ipfs" {
return nil, fmt.Errorf("unsupported path namespace: %s", pth.Namespace())
}

ipath := ipfspath.Path(pth.String())

ipldFetcher := bsfetcher.NewFetcherConfig(api.bsrv)
fetcher := ipldFetcher.WithReifier(unixfsnode.Reify)
resolver := ipfspathresolver.NewBasicResolver(fetcher)

node, rest, err := resolver.ResolveToLastNode(ctx, ipath)
if err != nil {
return nil, fmt.Errorf("resolve to last node: %w", err)
}

root, err := cid.Parse(ipath.Segments()[1])
if err != nil {
return nil, fmt.Errorf("parse root cid: %w", err)
}

return path.NewResolvedPath(ipath, node, root, gopath.Join(rest...)), nil
}

func (api *carGateway) resolveNode(ctx context.Context, pth path.Path) (ipld.Node, error) {
rp, err := api.resolvePath(ctx, pth)
if err != nil {
return nil, fmt.Errorf("resolve path: %w", err)
}

node, err := api.dsrv.Get(ctx, rp.Cid())
if err != nil {
return nil, fmt.Errorf("get node: %w", err)
}
return node, nil
}
58 changes: 58 additions & 0 deletions examples/gateway/car-file-gateway/block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"bytes"
"context"
"io"

iface "github.com/ipfs/interface-go-ipfs-core"
"github.com/ipfs/interface-go-ipfs-core/path"
)

type readerBlockAPI struct {
api *carGateway
}

func (r *readerBlockAPI) Get(ctx context.Context, pth path.Path) (io.Reader, error) {
rp, err := r.api.resolvePath(ctx, pth)
if err != nil {
return nil, err
}

b, err := r.api.bsrv.GetBlock(ctx, rp.Cid())
if err != nil {
return nil, err
}

return bytes.NewReader(b.RawData()), nil
}

func (r *readerBlockAPI) Stat(ctx context.Context, pth path.Path) (iface.BlockStat, error) {
rp, err := r.api.resolvePath(ctx, pth)
if err != nil {
return nil, err
}

b, err := r.api.bsrv.GetBlock(ctx, rp.Cid())
if err != nil {
return nil, err
}

return &BlockStat{
path: path.IpldPath(b.Cid()),
size: len(b.RawData()),
}, nil
}

type BlockStat struct {
size int
path path.Resolved
}

func (bs *BlockStat) Size() int {
return bs.size
}

func (bs *BlockStat) Path() path.Resolved {
return bs.path
}
104 changes: 104 additions & 0 deletions examples/gateway/car-file-gateway/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
module car-file-gateway

go 1.19

require (
github.com/ipfs/go-blockservice v0.5.0
github.com/ipfs/go-cid v0.3.2
github.com/ipfs/go-fetcher v1.6.1
github.com/ipfs/go-ipfs-blockstore v1.2.0
github.com/ipfs/go-ipfs-exchange-offline v0.3.0
github.com/ipfs/go-ipld-format v0.4.0
github.com/ipfs/go-libipfs v0.4.0
github.com/ipfs/go-merkledag v0.9.0
github.com/ipfs/go-path v0.3.0
github.com/ipfs/go-unixfs v0.3.1
github.com/ipfs/go-unixfsnode v1.5.1
github.com/ipfs/interface-go-ipfs-core v0.10.0
github.com/ipld/go-car v0.5.0
github.com/ipld/go-car/v2 v2.6.0
)

require (
github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/ipfs/bbloom v0.0.4 // indirect
github.com/ipfs/go-bitfield v1.0.0 // indirect
github.com/ipfs/go-block-format v0.1.1 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
github.com/ipfs/go-ipfs-chunker v0.0.1 // indirect
github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect
github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect
github.com/ipfs/go-ipfs-files v0.0.8 // indirect
github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect
github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect
github.com/ipfs/go-ipfs-util v0.0.2 // indirect
github.com/ipfs/go-ipld-cbor v0.0.6 // indirect
github.com/ipfs/go-ipld-legacy v0.1.1 // indirect
github.com/ipfs/go-ipns v0.3.0 // indirect
github.com/ipfs/go-log v1.0.5 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
github.com/ipfs/go-mfs v0.2.1 // indirect
github.com/ipfs/go-verifcid v0.0.2 // indirect
github.com/ipld/go-codec-dagpb v1.5.0 // indirect
github.com/ipld/go-ipld-prime v0.19.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.3 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.23.4 // indirect
github.com/libp2p/go-openssl v0.1.0 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr v0.8.0 // indirect
github.com/multiformats/go-multibase v0.1.1 // indirect
github.com/multiformats/go-multicodec v0.7.0 // indirect
github.com/multiformats/go-multihash v0.2.1 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/polydawn/refmt v0.89.0 // indirect
github.com/prometheus/client_golang v1.13.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/ucarion/urlpath v0.0.0-20200424170820-7ccc79b76bbb // indirect
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect
github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
go.opentelemetry.io/otel v1.12.0 // indirect
go.opentelemetry.io/otel/trace v1.12.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/exp v0.0.0-20230129154200-a960b3787bd2 // indirect
golang.org/x/net v0.5.0 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/protobuf v1.28.1 // indirect
lukechampine.com/blake3 v1.1.7 // indirect
)

replace github.com/ipfs/go-libipfs => ../../..
Loading

0 comments on commit 8f29e0a

Please sign in to comment.