Skip to content

Commit 963a812

Browse files
author
Lars Gierth
committed
GOODWIP
License: MIT Signed-off-by: Lars Gierth <[email protected]>
1 parent ce1a4ae commit 963a812

File tree

5 files changed

+127
-54
lines changed

5 files changed

+127
-54
lines changed

core/coreapi/coreapi.go

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import (
55

66
core "github.com/ipfs/go-ipfs/core"
77
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
8-
path "github.com/ipfs/go-ipfs/path"
8+
ipfspath "github.com/ipfs/go-ipfs/path"
99

10-
ipld "gx/ipfs/QmYDscK7dmdo2GZ9aumS8s5auUUAH5mR1jvj5pYhWusfK7/go-ipld-node"
10+
cid "gx/ipfs/QmV5gPoRsjN1Gid3LMdNZTyfCtP2DsvqEbMAmz82RmmiGk/go-cid"
1111
)
1212

1313
type CoreAPI struct {
@@ -23,17 +23,64 @@ func (api *CoreAPI) Unixfs() coreiface.UnixfsAPI {
2323
return (*UnixfsAPI)(api)
2424
}
2525

26-
func resolve(ctx context.Context, n *core.IpfsNode, p string) (ipld.Node, error) {
27-
pp, err := path.ParsePath(p)
26+
func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) {
27+
p, err := api.ResolvePath(ctx, p)
2828
if err != nil {
2929
return nil, err
3030
}
3131

32-
dagnode, err := core.Resolve(ctx, n.Namesys, n.Resolver, pp)
32+
node, err := api.node.DAG.Get(ctx, p.Cid())
33+
if err != nil {
34+
return nil, err
35+
}
36+
return node, nil
37+
}
38+
39+
func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreiface.Path, error) {
40+
if p.Resolved() {
41+
return p, nil
42+
}
43+
44+
p2 := ipfspath.FromString(p.String())
45+
node, err := core.Resolve(ctx, api.node.Namesys, api.node.Resolver, p2)
3346
if err == core.ErrNoNamesys {
3447
return nil, coreiface.ErrOffline
3548
} else if err != nil {
3649
return nil, err
3750
}
38-
return dagnode, nil
51+
52+
var root *cid.Cid
53+
if p2.IsJustAKey() {
54+
root = node.Cid()
55+
}
56+
57+
return ResolvedPath(p.String(), node.Cid(), root), nil
58+
}
59+
60+
// Implements coreiface.Path
61+
type path struct {
62+
path ipfspath.Path
63+
cid *cid.Cid
64+
root *cid.Cid
65+
}
66+
67+
func ParsePath(p string) (coreiface.Path, error) {
68+
pp, err := ipfspath.ParsePath(p)
69+
if err != nil {
70+
return nil, err
71+
}
72+
return &path{path: pp}, nil
3973
}
74+
75+
func ParseCid(c *cid.Cid) coreiface.Path {
76+
return &path{path: ipfspath.FromCid(c), cid: c, root: c}
77+
}
78+
79+
func ResolvedPath(p string, c *cid.Cid, r *cid.Cid) coreiface.Path {
80+
return &path{path: ipfspath.FromString(p), cid: c, root: r}
81+
}
82+
83+
func (p *path) String() string { return p.path.String() }
84+
func (p *path) Cid() *cid.Cid { return p.cid }
85+
func (p *path) Root() *cid.Cid { return p.root }
86+
func (p *path) Resolved() bool { return p.cid != nil }

core/coreapi/interface/interface.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ import (
99
ipld "gx/ipfs/QmYDscK7dmdo2GZ9aumS8s5auUUAH5mR1jvj5pYhWusfK7/go-ipld-node"
1010
)
1111

12+
type Path interface {
13+
String() string
14+
Cid() *cid.Cid
15+
Root() *cid.Cid
16+
Resolved() bool
17+
}
18+
19+
// TODO: should we really copy these?
20+
// if we didn't, godoc would generate nice links straight to go-ipld-node
21+
type Node ipld.Node
1222
type Link ipld.Link
1323

1424
type Reader interface {
@@ -18,12 +28,15 @@ type Reader interface {
1828

1929
type CoreAPI interface {
2030
Unixfs() UnixfsAPI
31+
ResolvePath(context.Context, Path) (Path, error)
32+
ResolveNode(context.Context, Path) (Node, error)
2133
}
2234

2335
type UnixfsAPI interface {
24-
Add(context.Context, io.Reader) (*cid.Cid, error)
25-
Cat(context.Context, string) (Reader, error)
26-
Ls(context.Context, string) ([]*Link, error)
36+
Core() CoreAPI
37+
Add(context.Context, io.Reader) (Path, error)
38+
Cat(context.Context, Path) (Reader, error)
39+
Ls(context.Context, Path) ([]*Link, error)
2740
}
2841

2942
// type ObjectAPI interface {
@@ -49,5 +62,4 @@ type UnixfsAPI interface {
4962
// }
5063

5164
var ErrIsDir = errors.New("object is a directory")
52-
var ErrIsNonDag = errors.New("not a merkledag object")
5365
var ErrOffline = errors.New("can't resolve, ipfs node is offline")

core/coreapi/unixfs.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@ import (
1313

1414
type UnixfsAPI CoreAPI
1515

16-
func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (*cid.Cid, error) {
16+
func (api *UnixfsAPI) Core() coreiface.CoreAPI {
17+
return (*CoreAPI)(api)
18+
}
19+
20+
func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.Path, error) {
1721
k, err := coreunix.AddWithContext(ctx, api.node, r)
1822
if err != nil {
1923
return nil, err
2024
}
21-
return cid.Decode(k)
25+
c, err := cid.Decode(k)
26+
if err != nil {
27+
return nil, err
28+
}
29+
return ParseCid(c), nil
2230
}
2331

24-
func (api *UnixfsAPI) Cat(ctx context.Context, p string) (coreiface.Reader, error) {
25-
dagnode, err := resolve(ctx, api.node, p)
32+
func (api *UnixfsAPI) Cat(ctx context.Context, p coreiface.Path) (coreiface.Reader, error) {
33+
dagnode, err := api.Core().ResolveNode(ctx, p)
2634
if err != nil {
2735
return nil, err
2836
}
@@ -36,8 +44,8 @@ func (api *UnixfsAPI) Cat(ctx context.Context, p string) (coreiface.Reader, erro
3644
return r, nil
3745
}
3846

39-
func (api *UnixfsAPI) Ls(ctx context.Context, p string) ([]*coreiface.Link, error) {
40-
dagnode, err := resolve(ctx, api.node, p)
47+
func (api *UnixfsAPI) Ls(ctx context.Context, p coreiface.Path) ([]*coreiface.Link, error) {
48+
dagnode, err := api.Core().ResolveNode(ctx, p)
4149
if err != nil {
4250
return nil, err
4351
}

core/coreapi/unixfs_test.go

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ import (
1919
)
2020

2121
// `echo -n 'hello, world!' | ipfs add`
22-
var hello = "QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk"
22+
var hello = coreapi.ResolvedPath("/ipfs/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk", nil, nil)
2323
var helloStr = "hello, world!"
2424

2525
// `ipfs object new unixfs-dir`
26-
var emptyUnixfsDir = "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn"
26+
var emptyDir = coreapi.ResolvedPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn", nil, nil)
2727

2828
// `echo -n | ipfs add`
29-
var emptyUnixfsFile = "QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH"
29+
var emptyFile = coreapi.ResolvedPath("/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH", nil, nil)
3030

3131
func makeAPI(ctx context.Context) (*core.IpfsNode, coreiface.UnixfsAPI, error) {
3232
r := &repo.Mock{
@@ -53,13 +53,13 @@ func TestAdd(t *testing.T) {
5353
}
5454

5555
str := strings.NewReader(helloStr)
56-
c, err := api.Add(ctx, str)
56+
p, err := api.Add(ctx, str)
5757
if err != nil {
5858
t.Error(err)
5959
}
6060

61-
if c.String() != hello {
62-
t.Fatalf("expected CID %s, got: %s", hello, c)
61+
if p.String() != hello.String() {
62+
t.Fatalf("expected CID %s, got: %s", hello, p)
6363
}
6464

6565
r, err := api.Cat(ctx, hello)
@@ -90,7 +90,7 @@ func TestAddEmptyFile(t *testing.T) {
9090
t.Error(err)
9191
}
9292

93-
if c.String() != emptyUnixfsFile {
93+
if c.String() != emptyFile.String() {
9494
t.Fatalf("expected CID %s, got: %s", hello, c)
9595
}
9696
}
@@ -103,16 +103,17 @@ func TestCatBasic(t *testing.T) {
103103
}
104104

105105
hr := strings.NewReader(helloStr)
106-
k, err := coreunix.Add(node, hr)
106+
p, err := coreunix.Add(node, hr)
107107
if err != nil {
108108
t.Fatal(err)
109109
}
110+
p = "/ipfs/" + p
110111

111-
if k != hello {
112-
t.Fatalf("expected CID %s, got: %s", hello, k)
112+
if p != hello.String() {
113+
t.Fatalf("expected CID %s, got: %s", hello, p)
113114
}
114115

115-
r, err := api.Cat(ctx, k)
116+
r, err := api.Cat(ctx, hello)
116117
if err != nil {
117118
t.Fatal(err)
118119
}
@@ -139,7 +140,7 @@ func TestCatEmptyFile(t *testing.T) {
139140
t.Fatal(err)
140141
}
141142

142-
r, err := api.Cat(ctx, emptyUnixfsFile)
143+
r, err := api.Cat(ctx, emptyFile)
143144
if err != nil {
144145
t.Fatal(err)
145146
}
@@ -165,8 +166,13 @@ func TestCatDir(t *testing.T) {
165166
if err != nil {
166167
t.Error(err)
167168
}
169+
p := coreapi.ParseCid(c)
168170

169-
_, err = api.Cat(ctx, c.String())
171+
if p.String() != emptyDir.String() {
172+
t.Fatalf("expected CID %s, got: %s", emptyDir, p)
173+
}
174+
175+
_, err = api.Cat(ctx, emptyDir)
170176
if err != coreiface.ErrIsDir {
171177
t.Fatalf("expected ErrIsDir, got: %s", err)
172178
}
@@ -179,12 +185,12 @@ func TestCatNonUnixfs(t *testing.T) {
179185
t.Error(err)
180186
}
181187

182-
c, err := node.DAG.Add(new(mdag.ProtoNode))
188+
p, err := node.DAG.Add(new(mdag.ProtoNode))
183189
if err != nil {
184190
t.Error(err)
185191
}
186192

187-
_, err = api.Cat(ctx, c.String())
193+
_, err = api.Cat(ctx, coreapi.ParseCid(p))
188194
if !strings.Contains(err.Error(), "proto: required field") {
189195
t.Fatalf("expected protobuf error, got: %s", err)
190196
}
@@ -197,7 +203,7 @@ func TestCatOffline(t *testing.T) {
197203
t.Error(err)
198204
}
199205

200-
_, err = api.Cat(ctx, "/ipns/Qmfoobar")
206+
_, err = api.Cat(ctx, coreapi.ResolvedPath("/ipns/Qmfoobar", nil, nil))
201207
if err != coreiface.ErrOffline {
202208
t.Fatalf("expected ErrOffline, got: %", err)
203209
}
@@ -211,17 +217,17 @@ func TestLs(t *testing.T) {
211217
}
212218

213219
r := strings.NewReader("content-of-file")
214-
p, _, err := coreunix.AddWrapped(node, r, "name-of-file")
220+
k, _, err := coreunix.AddWrapped(node, r, "name-of-file")
215221
if err != nil {
216222
t.Error(err)
217223
}
218-
parts := strings.Split(p, "/")
224+
parts := strings.Split(k, "/")
219225
if len(parts) != 2 {
220-
t.Errorf("unexpected path:", p)
226+
t.Errorf("unexpected path:", k)
221227
}
222-
k := parts[0]
228+
p := coreapi.ResolvedPath("/ipfs/"+parts[0], nil, nil)
223229

224-
links, err := api.Ls(ctx, k)
230+
links, err := api.Ls(ctx, p)
225231
if err != nil {
226232
t.Error(err)
227233
}
@@ -236,7 +242,7 @@ func TestLs(t *testing.T) {
236242
t.Fatalf("expected name = name-of-file, got %s", links[0].Name)
237243
}
238244
if links[0].Cid.String() != "QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr" {
239-
t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", links[0].Cid.String())
245+
t.Fatalf("expected cid = QmX3qQVKxDGz3URVC3861Z3CKtQKGBn6ffXRBBWGMFz9Lr, got %s", links[0].Cid)
240246
}
241247
}
242248

@@ -247,12 +253,12 @@ func TestLsEmptyDir(t *testing.T) {
247253
t.Error(err)
248254
}
249255

250-
c, err := node.DAG.Add(unixfs.EmptyDirNode())
256+
_, err = node.DAG.Add(unixfs.EmptyDirNode())
251257
if err != nil {
252258
t.Error(err)
253259
}
254260

255-
links, err := api.Ls(ctx, c.String())
261+
links, err := api.Ls(ctx, emptyDir)
256262
if err != nil {
257263
t.Error(err)
258264
}
@@ -275,7 +281,7 @@ func TestLsNonUnixfs(t *testing.T) {
275281
t.Error(err)
276282
}
277283

278-
links, err := api.Ls(ctx, c.String())
284+
links, err := api.Ls(ctx, coreapi.ParseCid(c))
279285
if err != nil {
280286
t.Error(err)
281287
}

core/corehttp/gateway_handler.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"time"
1313

1414
core "github.com/ipfs/go-ipfs/core"
15+
coreapi "github.com/ipfs/go-ipfs/core/coreapi"
1516
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
1617
"github.com/ipfs/go-ipfs/importer"
1718
chunk "github.com/ipfs/go-ipfs/importer/chunk"
@@ -158,7 +159,13 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
158159
ipnsHostname = true
159160
}
160161

161-
dr, err := i.api.Unixfs().Cat(ctx, urlPath)
162+
parsedPath, err := coreapi.ParsePath(urlPath)
163+
if err != nil {
164+
webError(w, "invalid ipfs path", err, http.StatusBadRequest)
165+
return
166+
}
167+
168+
dr, err := i.api.Unixfs().Cat(ctx, parsedPath)
162169
dir := false
163170
switch err {
164171
case nil:
@@ -218,7 +225,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
218225
return
219226
}
220227

221-
links, err := i.api.Unixfs().Ls(ctx, urlPath)
228+
links, err := i.api.Unixfs().Ls(ctx, parsedPath)
222229
if err != nil {
223230
internalWebError(w, err)
224231
return
@@ -240,14 +247,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
240247
return
241248
}
242249

243-
p, err := path.ParsePath(urlPath + "/index.html")
244-
if err != nil {
245-
internalWebError(w, err)
246-
return
247-
}
248-
249-
// return index page instead.
250-
dr, err := i.api.Unixfs().Cat(ctx, p.String())
250+
dr, err := i.api.Unixfs().Cat(ctx, coreapi.ParseCid(link.Cid))
251251
if err != nil {
252252
internalWebError(w, err)
253253
return
@@ -314,15 +314,15 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
314314
}
315315

316316
func (i *gatewayHandler) postHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
317-
k, err := i.api.Unixfs().Add(ctx, r.Body)
317+
p, err := i.api.Unixfs().Add(ctx, r.Body)
318318
if err != nil {
319319
internalWebError(w, err)
320320
return
321321
}
322322

323323
i.addUserHeaders(w) // ok, _now_ write user's headers.
324-
w.Header().Set("IPFS-Hash", k.String())
325-
http.Redirect(w, r, ipfsPathPrefix+k.String(), http.StatusCreated)
324+
w.Header().Set("IPFS-Hash", p.Cid().String())
325+
http.Redirect(w, r, p.String(), http.StatusCreated)
326326
}
327327

328328
func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {

0 commit comments

Comments
 (0)