@cryptotaxi247 / kubo / commits / d2836de57

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