From b39bc78cb03ddde76ff5bdeb2afb365405472308 Mon Sep 17 00:00:00 2001 From: Travis Ralston <travpc@gmail.com> Date: Wed, 4 Mar 2020 20:55:10 -0700 Subject: [PATCH] Early support for putting files into IPFS (not wired) --- go.mod | 1 + ipfs_proxy/api.go | 6 ++++++ ipfs_proxy/iface.go | 3 +++ ipfs_proxy/ipfs_embedded/impl.go | 32 +++++++++++++++++++++++++------- ipfs_proxy/ipfs_local/impl.go | 11 +++++++++++ 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 5b1ff211..34ffdba5 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/ipfs/go-cid v0.0.4 github.com/ipfs/go-ipfs v0.4.22-0.20191119151441-b8ec598d5801 github.com/ipfs/go-ipfs-config v0.0.11 + github.com/ipfs/go-ipfs-files v0.0.4 github.com/ipfs/go-ipfs-http-client v0.0.5 github.com/ipfs/interface-go-ipfs-core v0.2.6 github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect diff --git a/ipfs_proxy/api.go b/ipfs_proxy/api.go index 0be12796..ba61094b 100644 --- a/ipfs_proxy/api.go +++ b/ipfs_proxy/api.go @@ -1,6 +1,8 @@ package ipfs_proxy import ( + "io" + "github.com/sirupsen/logrus" "github.com/turt2live/matrix-media-repo/common/config" "github.com/turt2live/matrix-media-repo/common/rcontext" @@ -59,3 +61,7 @@ func getImpl() IPFSImplementation { func GetObject(contentId string, ctx rcontext.RequestContext) (*ipfs_models.IPFSObject, error) { return getImpl().GetObject(contentId, ctx) } + +func PutObject(data io.Reader, ctx rcontext.RequestContext) (string, error) { + return getImpl().PutObject(data, ctx) +} diff --git a/ipfs_proxy/iface.go b/ipfs_proxy/iface.go index 6fa26de4..e80a5518 100644 --- a/ipfs_proxy/iface.go +++ b/ipfs_proxy/iface.go @@ -1,11 +1,14 @@ package ipfs_proxy import ( + "io" + "github.com/turt2live/matrix-media-repo/common/rcontext" "github.com/turt2live/matrix-media-repo/ipfs_proxy/ipfs_models" ) type IPFSImplementation interface { GetObject(contentId string, ctx rcontext.RequestContext) (*ipfs_models.IPFSObject, error) + PutObject(data io.Reader, ctx rcontext.RequestContext) (string, error) Stop() } diff --git a/ipfs_proxy/ipfs_embedded/impl.go b/ipfs_proxy/ipfs_embedded/impl.go index 24b59f7a..d348f4f1 100644 --- a/ipfs_proxy/ipfs_embedded/impl.go +++ b/ipfs_proxy/ipfs_embedded/impl.go @@ -3,6 +3,7 @@ package ipfs_embedded import ( "bytes" "context" + "io" "io/ioutil" "path/filepath" "sync" @@ -10,6 +11,7 @@ import ( "github.com/ipfs/go-cid" ipfsConfig "github.com/ipfs/go-ipfs-config" + files "github.com/ipfs/go-ipfs-files" "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi" "github.com/ipfs/go-ipfs/core/node/libp2p" @@ -27,14 +29,18 @@ import ( ) type IPFSEmbedded struct { - api icore.CoreAPI - node *core.IpfsNode + api icore.CoreAPI + node *core.IpfsNode + ctx context.Context + cancelCtxFn context.CancelFunc } func NewEmbeddedIPFSNode() (IPFSEmbedded, error) { // Startup routine modified from: // https://github.com/ipfs/go-ipfs/blob/083ef47ce84a5bd9a93f0ce0afaf668881dc1f35/docs/examples/go-ipfs-as-a-library/main.go + ctx, cancel := context.WithCancel(context.Background()) + blank := IPFSEmbedded{} // Load plugins @@ -85,7 +91,7 @@ func NewEmbeddedIPFSNode() (IPFSEmbedded, error) { } logrus.Info("Building IPFS embedded node") - node, err := core.NewNode(context.Background(), nodeOptions) + node, err := core.NewNode(ctx, nodeOptions) if err != nil { return blank, err } @@ -135,7 +141,7 @@ func NewEmbeddedIPFSNode() (IPFSEmbedded, error) { for _, peerInfo := range peerInfos { go func(peerInfo *peerstore.PeerInfo) { defer wg.Done() - err := api.Swarm().Connect(context.Background(), *peerInfo) + err := api.Swarm().Connect(ctx, *peerInfo) if err != nil { logrus.Error(err) } else { @@ -147,8 +153,10 @@ func NewEmbeddedIPFSNode() (IPFSEmbedded, error) { logrus.Info("Done building IPFS embedded node") return IPFSEmbedded{ - api: api, - node: node, + api: api, + node: node, + ctx: ctx, + cancelCtxFn: cancel, }, nil } @@ -160,7 +168,7 @@ func (i IPFSEmbedded) GetObject(contentId string, ctx rcontext.RequestContext) ( } ctx.Log.Info("Resolving path and node") - timeoutCtx, cancel := context.WithTimeout(ctx.Context, 10 * time.Second) + timeoutCtx, cancel := context.WithTimeout(ctx.Context, 10*time.Second) defer cancel() ipfsPath := icorepath.IpfsPath(ipfsCid) node, err := i.api.ResolveNode(timeoutCtx, ipfsPath) @@ -177,6 +185,16 @@ func (i IPFSEmbedded) GetObject(contentId string, ctx rcontext.RequestContext) ( }, nil } +func (i IPFSEmbedded) PutObject(data io.Reader, ctx rcontext.RequestContext) (string, error) { + ipfsFile := files.NewReaderFile(data) + p, err := i.api.Unixfs().Add(ctx.Context, ipfsFile) + if err != nil { + return "", err + } + return p.Cid().String(), nil +} + func (i IPFSEmbedded) Stop() { + i.cancelCtxFn() i.node.Close() } diff --git a/ipfs_proxy/ipfs_local/impl.go b/ipfs_proxy/ipfs_local/impl.go index f37cb699..25c38dec 100644 --- a/ipfs_proxy/ipfs_local/impl.go +++ b/ipfs_proxy/ipfs_local/impl.go @@ -2,8 +2,10 @@ package ipfs_local import ( "bytes" + "io" "github.com/ipfs/go-cid" + files "github.com/ipfs/go-ipfs-files" httpapi "github.com/ipfs/go-ipfs-http-client" "github.com/ipfs/interface-go-ipfs-core/path" "github.com/turt2live/matrix-media-repo/common/rcontext" @@ -42,6 +44,15 @@ func (i IPFSLocal) GetObject(contentId string, ctx rcontext.RequestContext) (*ip }, nil } +func (i IPFSLocal) PutObject(data io.Reader, ctx rcontext.RequestContext) (string, error) { + ipfsFile := files.NewReaderFile(data) + p, err := i.client.Unixfs().Add(ctx.Context, ipfsFile) + if err != nil { + return "", err + } + return p.Cid().String(), nil +} + func (i IPFSLocal) Stop() { // Nothing to do } -- GitLab