core/corehttp/gateway_handler: pass a request ctx instead of the node ctx
License: MIT Signed-off-by: Georgij Tolstov <tolstov.georgij@gmail.com>
tg committed
Apr 22, 2019 at 20:39 UTC
d2836de5774efea366301298bfc363a95b0d6fab
1 file changed
+41
-33
core/corehttp/gateway_handler.go
+41
-33
@@ -19,7 +19,7 @@ import (
19
"github.com/dustin/go-humanize"
20
"github.com/ipfs/go-cid"
21
chunker "github.com/ipfs/go-ipfs-chunker"
22
- "github.com/ipfs/go-ipfs-files"
22
+ files "github.com/ipfs/go-ipfs-files"
23
ipld "github.com/ipfs/go-ipld-format"
24
dag "github.com/ipfs/go-merkledag"
25
"github.com/ipfs/go-path"
@@ -28,7 +28,7 @@ import (
28
"github.com/ipfs/go-unixfs/importer"
29
coreiface "github.com/ipfs/interface-go-ipfs-core"
30
ipath "github.com/ipfs/interface-go-ipfs-core/path"
31
- "github.com/libp2p/go-libp2p-routing"
31
+ routing "github.com/libp2p/go-libp2p-routing"
32
"github.com/multiformats/go-multibase"
33
)
34
@@ -67,6 +67,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
67
// the hour is a hard fallback, we don't expect it to happen, but just in case
68
ctx, cancel := context.WithTimeout(r.Context(), time.Hour)
69
defer cancel()
70
+ r = r.WithContext(ctx)
71
72
defer func() {
73
if r := recover(); r != nil {
@@ -79,7 +80,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
80
if i.config.Writable {
81
switch r.Method {
82
case "POST":
82
- i.postHandler(ctx, w, r)
83
+ i.postHandler(w, r)
84
return
85
case "PUT":
86
i.putHandler(w, r)
@@ -91,7 +92,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
92
}
93
94
if r.Method == "GET" || r.Method == "HEAD" {
94
- i.getOrHeadHandler(ctx, w, r)
95
+ i.getOrHeadHandler(w, r)
96
return
97
}
98
@@ -120,7 +121,7 @@ func (i *gatewayHandler) optionsHandler(w http.ResponseWriter, r *http.Request)
121
i.addUserHeaders(w) // return all custom headers (including CORS ones, if set)
122
}
123
123
-func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
124
+func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request) {
125
urlPath := r.URL.Path
126
escapedURLPath := r.URL.EscapedPath()
127
@@ -156,7 +157,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
157
}
158
159
// Resolve path to the final DAG node for the ETag
159
- resolvedPath, err := i.api.ResolvePath(ctx, parsedPath)
160
+ resolvedPath, err := i.api.ResolvePath(r.Context(), parsedPath)
161
if err == coreiface.ErrOffline && !i.node.IsOnline {
162
webError(w, "ipfs resolve -r "+escapedURLPath, err, http.StatusServiceUnavailable)
163
return
@@ -165,7 +166,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
166
return
167
}
168
168
- dr, err := i.api.Unixfs().Get(ctx, resolvedPath)
169
+ dr, err := i.api.Unixfs().Get(r.Context(), resolvedPath)
170
if err != nil {
171
webError(w, "ipfs cat "+escapedURLPath, err, http.StatusNotFound)
172
return
@@ -248,7 +249,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
249
return
250
}
251
251
- idx, err := i.api.Unixfs().Get(ctx, ipath.Join(resolvedPath, "index.html"))
252
+ idx, err := i.api.Unixfs().Get(r.Context(), ipath.Join(resolvedPath, "index.html"))
253
switch err.(type) {
254
case nil:
255
dirwithoutslash := urlPath[len(urlPath)-1] != '/'
@@ -377,8 +378,8 @@ func (i *gatewayHandler) serveFile(w http.ResponseWriter, req *http.Request, nam
378
http.ServeContent(w, req, name, modtime, content)
379
}
380
380
-func (i *gatewayHandler) postHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
381
- p, err := i.api.Unixfs().Add(ctx, files.NewReaderFile(r.Body))
381
+func (i *gatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) {
382
+ p, err := i.api.Unixfs().Add(r.Context(), files.NewReaderFile(r.Body))
383
if err != nil {
384
internalWebError(w, err)
385
return
@@ -390,10 +391,6 @@ func (i *gatewayHandler) postHandler(ctx context.Context, w http.ResponseWriter,
391
}
392
393
func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
393
- // TODO(cryptix): move me to ServeHTTP and pass into all handlers
394
- ctx, cancel := context.WithCancel(i.node.Context())
395
- defer cancel()
396
-
394
rootPath, err := path.ParsePath(r.URL.Path)
395
if err != nil {
396
webError(w, "putHandler: IPFS path not valid", err, http.StatusBadRequest)
@@ -424,7 +421,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
421
}
422
423
var newcid cid.Cid
427
- rnode, err := resolve.Resolve(ctx, i.node.Namesys, i.node.Resolver, rootPath)
424
+ rnode, err := resolve.Resolve(r.Context(), i.node.Namesys, i.node.Resolver, rootPath)
425
switch ev := err.(type) {
426
case resolver.ErrNoLink:
427
// ev.Node < node where resolve failed
@@ -436,7 +433,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
433
return
434
}
435
439
- rnode, err := i.node.DAG.Get(ctx, c)
436
+ rnode, err := i.node.DAG.Get(r.Context(), c)
437
if err != nil {
438
webError(w, "putHandler: Could not create DAG from request", err, http.StatusInternalServerError)
439
return
@@ -449,13 +446,13 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
446
}
447
448
e := dagutils.NewDagEditor(pbnd, i.node.DAG)
452
- err = e.InsertNodeAtPath(ctx, newPath, newnode, ft.EmptyDirNode)
449
+ err = e.InsertNodeAtPath(r.Context(), newPath, newnode, ft.EmptyDirNode)
450
if err != nil {
451
webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError)
452
return
453
}
454
458
- nnode, err := e.Finalize(ctx, i.node.DAG)
455
+ nnode, err := e.Finalize(r.Context(), i.node.DAG)
456
if err != nil {
457
webError(w, "putHandler: could not get node", err, http.StatusInternalServerError)
458
return
@@ -480,7 +477,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
477
pbnd.SetData(pbnewnode.Data())
478
479
newcid = pbnd.Cid()
483
- err = i.node.DAG.Add(ctx, pbnd)
480
+ err = i.node.DAG.Add(r.Context(), pbnd)
481
if err != nil {
482
nnk := newnode.Cid()
483
webError(w, fmt.Sprintf("putHandler: Could not add newnode(%q) to root(%q)", nnk.String(), newcid.String()), err, http.StatusInternalServerError)
@@ -498,8 +495,6 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
495
496
func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
497
urlPath := r.URL.Path
501
- ctx, cancel := context.WithCancel(i.node.Context())
502
- defer cancel()
498
499
p, err := path.ParsePath(urlPath)
500
if err != nil {
@@ -513,17 +508,9 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
508
return
509
}
510
516
- tctx, cancel := context.WithTimeout(ctx, time.Minute)
517
- defer cancel()
518
- rootnd, err := i.node.Resolver.DAG.Get(tctx, c)
519
- if err != nil {
520
- webError(w, "Could not resolve root object", err, http.StatusBadRequest)
521
- return
522
- }
523
-
524
- pathNodes, err := i.node.Resolver.ResolveLinks(tctx, rootnd, components[:len(components)-1])
511
+ pathNodes, err := i.resolvePathComponents(r.Context(), c, components)
512
if err != nil {
526
- webError(w, "Could not resolve parent object", err, http.StatusBadRequest)
513
+ webError(w, "Could not resolve path components", err, http.StatusBadRequest)
514
return
515
}
516
@@ -542,7 +529,7 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
529
530
var newnode *dag.ProtoNode = pbnd
531
for j := len(pathNodes) - 2; j >= 0; j-- {
545
- if err := i.node.DAG.Add(ctx, newnode); err != nil {
532
+ if err := i.node.DAG.Add(r.Context(), newnode); err != nil {
533
webError(w, "Could not add node", err, http.StatusInternalServerError)
534
return
535
}
@@ -560,7 +547,7 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
547
}
548
}
549
563
- if err := i.node.DAG.Add(ctx, newnode); err != nil {
550
+ if err := i.node.DAG.Add(r.Context(), newnode); err != nil {
551
webError(w, "Could not add root node", err, http.StatusInternalServerError)
552
return
553
}
@@ -573,6 +560,27 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
560
http.Redirect(w, r, gopath.Join(ipfsPathPrefix+ncid.String(), path.Join(components[:len(components)-1])), http.StatusCreated)
561
}
562
563
+func (i *gatewayHandler) resolvePathComponents(
564
+ ctx context.Context,
565
+ c cid.Cid,
566
+ components []string,
567
+) ([]ipld.Node, error) {
568
+ tctx, cancel := context.WithTimeout(ctx, time.Minute)
569
+ defer cancel()
570
+
571
+ rootnd, err := i.node.Resolver.DAG.Get(tctx, c)
572
+ if err != nil {
573
+ return nil, fmt.Errorf("Could not resolve root object: %s", err)
574
+ }
575
+
576
+ pathNodes, err := i.node.Resolver.ResolveLinks(tctx, rootnd, components[:len(components)-1])
577
+ if err != nil {
578
+ return nil, fmt.Errorf("Could not resolve parent object: %s", err)
579
+ }
580
+
581
+ return pathNodes, nil
582
+}
583
+
584
func (i *gatewayHandler) addUserHeaders(w http.ResponseWriter) {
585
for k, v := range i.config.Headers {
586
w.Header()[k] = v