/
files.go
134 lines (120 loc) · 2.9 KB
/
files.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package handler
import (
"bytes"
"fmt"
"io"
"net/http"
"strings"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/codec/raw"
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
"github.com/ipld/go-ipld-prime/node/basicnode"
"github.com/spf13/cast"
"github.com/gin-gonic/gin"
"github.com/ipfs/go-cid"
)
// @BasePath /v0
// FileWrite godoc
// @Summary Stores files
// @Schemes
// @Description Writes a raw block which syncs with IPFS. Returns a CID.
// @Tags file
// @Accept json
// @Produce json
// @Success 201 {string} cid
// @Router /v0/file [post]
func (dagctx *AnconSyncContext) FileWrite(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.JSON(400, gin.H{
"error": fmt.Errorf("error in form file %v", err).Error(),
})
return
}
src, err := file.Open()
if err != nil {
c.JSON(400, gin.H{
"error": fmt.Errorf("cannot open file. %v", err).Error(),
})
return
}
defer src.Close()
// var bz []byte
var w bytes.Buffer
_, err = io.Copy(&w, src)
if err != nil {
c.JSON(400, gin.H{
"error": fmt.Errorf("failed reading file. %v", err).Error(),
})
return
}
n, err := DecodeNode(w.Bytes())
lnk := dagctx.Store.Store(ipld.LinkContext{
LinkPath: ipld.ParsePath(strings.Join([]string{"/", file.Filename}, "/")),
}, n)
if err != nil {
c.JSON(400, gin.H{
"error": fmt.Errorf("cid error. %v", err).Error(),
})
return
}
c.JSON(201, gin.H{
"cid": lnk.String(),
})
PushBlock(c.Request.Context(), dagctx, lnk)
}
// @BasePath /v0
// FileRead godoc
// @Summary Reads JSON from a dag-json block
// @Schemes
// @Description Returns JSON
// @Tags file
// @Accept json
// @Produce json
// @Success 200
// @Router /v0/file/{cid}/{path} [get]
func (dagctx *AnconSyncContext) FileRead(c *gin.Context) {
lnk, err := cid.Parse(c.Param("cid"))
if err != nil {
c.JSON(400, gin.H{
"error": fmt.Errorf("cid error. %v", err).Error(),
})
return
}
n, err := dagctx.Store.Load(ipld.LinkContext{LinkPath: ipld.ParsePath(c.Param("path"))}, cidlink.Link{Cid: lnk})
if err != nil {
c.JSON(400, gin.H{
"error": fmt.Errorf("%v", err),
})
return
}
bz, err := EncodeNode(n)
if err != nil {
c.JSON(400, gin.H{
"error": fmt.Errorf("error while getting stream. %v", err).Error(),
})
return
}
contentLength := cast.ToInt64(-1)
contentType := c.ContentType()
extraHeaders := map[string]string{
// "Content-Disposition": `attachment; filename="gopher.png"`,
}
reader := bytes.NewReader(bz)
c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
}
func EncodeNode(node ipld.Node) ([]byte, error) {
var buffer bytes.Buffer
err := raw.Encode(node, &buffer)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func DecodeNode(encoded []byte) (ipld.Node, error) {
nb := basicnode.Prototype.Any.NewBuilder()
if err := raw.Decode(nb, bytes.NewReader(encoded)); err != nil {
return nil, err
}
return nb.Build(), nil
}