diff --git a/go.mod b/go.mod index 5b1ff211661b8873917cdd56c34674080e555286..34ffdba5a712c27fc37b6c5018c994793f6f2016 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 0be1279639e0368c7ef5de07a23f6a4bf96ee356..ba61094bf181f66da78492a15bba72af30f7fd8b 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 6fa26de48f321d870bfe11ae4d1205aac204f439..e80a55189c8001de2f36f9a754dc345e2b987d9c 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 24b59f7a51bba4e66992747d0ed777fca474fe71..d348f4f1ae0061b6030cf5e77283d21062bbc623 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 f37cb699528e9abfd2f60beb1183aadab3233cd7..25c38dec9cb9761b7b40cb3c3647a874e7f31b77 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 }