Skip to content

Commit

Permalink
ipfs: all - major refactor
Browse files Browse the repository at this point in the history
- Add caching mechanism to IPFS, IPNS, and PinFS
- Change constructors for all, specifically how options are handled
- Change field parser logic for mount-point file
- Various minor bugfixes
  • Loading branch information
djdv committed Apr 3, 2023
1 parent b4fcc93 commit 81da6bd
Show file tree
Hide file tree
Showing 14 changed files with 2,268 additions and 902 deletions.
41 changes: 41 additions & 0 deletions internal/filesystem/ipfs/cbor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package ipfs

import (
"bytes"
"io"
"io/fs"

cbor "github.com/ipfs/go-ipld-cbor"
)

type cborFile struct {
reader io.ReadSeeker
node *cbor.Node
info nodeInfo
}

func (cio *cborFile) Close() error { return nil }

func (cio *cborFile) Stat() (fs.FileInfo, error) { return &cio.info, nil }
func (cio *cborFile) Read(buff []byte) (int, error) { return cio.reader.Read(buff) }

func (cio *cborFile) Seek(offset int64, whence int) (int64, error) {
return cio.reader.Seek(offset, whence)
}

func openCborFile(cborNode *cbor.Node, info *nodeInfo) *cborFile {
return &cborFile{
node: cborNode,
reader: bytes.NewReader(cborNode.RawData()),
info: *info,
}
}

func statCbor(node *cbor.Node, info *nodeInfo) error {
size, err := node.Size()
if err != nil {
return err
}
info.size = int64(size)
return nil
}
87 changes: 87 additions & 0 deletions internal/filesystem/ipfs/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package ipfs

import (
"context"
"errors"
"net"
"net/http"
"time"

httpapi "github.com/ipfs/go-ipfs-http-client"
"github.com/multiformats/go-multiaddr"
madns "github.com/multiformats/go-multiaddr-dns"
manet "github.com/multiformats/go-multiaddr/net"
)

func newIPFSClient(apiMaddr multiaddr.Multiaddr) (*httpapi.HttpApi, error) {
address, client, err := newHTTPClient(apiMaddr)
if err != nil {
return nil, err
}
return httpapi.NewURLApiWithClient(address, client)
}

func newHTTPClient(apiMaddr multiaddr.Multiaddr) (string, *http.Client, error) {
const timeout = 30 * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
resolvedMaddr, err := resolveMaddr(ctx, apiMaddr)
if err != nil {
return "", nil, err
}

network, address, err := manet.DialArgs(resolvedMaddr)
if err != nil {
return "", nil, err
}
var client *http.Client
switch network {
case "unix":
// NOTE: [go-ipfs-http-client] would need to patch [httpaoi.NewApi]
// to handle this internally.
// Without a custom `http.Client`, `httpapi.HttpApi` fails when
// making requests to unix domain sockets.
address, client = udsHTTPClient(address)
default:
client = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DisableKeepAlives: true,
},
}
}
return address, client, nil
}

func udsHTTPClient(address string) (string, *http.Client) {
var (
// NOTE: `http+unix` scheme is not supported in Go (1.20)
// udsUrl = "http+unix://" + url.PathEscape(address)
// BUG: [httpapi.NewRequest] always prepends `http://`
// if prefix is not `http`; which would mangle our url anyway.
fakeAddress = "http://unix-domain-socket"
netDialer = new(net.Dialer)
client = &http.Client{
Transport: &http.Transport{
DisableKeepAlives: true,
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
return netDialer.DialContext(ctx, "unix", address)
},
},
}
)
return fakeAddress, client
}

func resolveMaddr(ctx context.Context, addr multiaddr.Multiaddr) (multiaddr.Multiaddr, error) {
addrs, err := madns.DefaultResolver.Resolve(ctx, addr)
if err != nil {
return nil, err
}

if len(addrs) == 0 {
return nil, errors.New("non-resolvable API endpoint")
}

return addrs[0], nil
}
Loading

0 comments on commit 81da6bd

Please sign in to comment.