@cryptotaxi247 / kubo / commits / 9bd346e25

fix: fix context plumbing in gateway handlers (#8871)

This ensures that child contexts are passed around between the handlers so that traces show the call hierarchy correctly.

Gus Eggert committed Apr 11, 2022 at 17:09 UTC 9bd346e25004df4fd7927ab151097f975fb433c2
6 files changed +22 -18
core/corehttp/gateway_handler.go
+3 -3
@@ -443,16 +443,16 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
443 switch responseFormat {
444 case "": // The implicit response format is UnixFS
445 logger.Debugw("serving unixfs", "path", contentPath)
446 - i.serveUnixFs(w, r, resolvedPath, contentPath, begin, logger)
446 + i.serveUnixFS(r.Context(), w, r, resolvedPath, contentPath, begin, logger)
447 return
448 case "application/vnd.ipld.raw":
449 logger.Debugw("serving raw block", "path", contentPath)
450 - i.serveRawBlock(w, r, resolvedPath, contentPath, begin)
450 + i.serveRawBlock(r.Context(), w, r, resolvedPath, contentPath, begin)
451 return
452 case "application/vnd.ipld.car":
453 logger.Debugw("serving car stream", "path", contentPath)
454 carVersion := formatParams["version"]
455 - i.serveCar(w, r, resolvedPath, contentPath, carVersion, begin)
455 + i.serveCAR(r.Context(), w, r, resolvedPath, contentPath, carVersion, begin)
456 return
457 default: // catch-all for unsuported application/vnd.*
458 err := fmt.Errorf("unsupported format %q", responseFormat)
core/corehttp/gateway_handler_block.go
+3 -2
@@ -2,6 +2,7 @@ package corehttp
2
3 import (
4 "bytes"
5 + "context"
6 "io/ioutil"
7 "net/http"
8 "time"
@@ -13,8 +14,8 @@ import (
14 )
15
16 // serveRawBlock returns bytes behind a raw block
16 -func (i *gatewayHandler) serveRawBlock(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time) {
17 - ctx, span := tracing.Span(r.Context(), "Gateway", "ServeRawBlock", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
17 +func (i *gatewayHandler) serveRawBlock(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time) {
18 + ctx, span := tracing.Span(ctx, "Gateway", "ServeRawBlock", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
19 defer span.End()
20 blockCid := resolvedPath.Cid()
21 blockReader, err := i.api.Block().Get(ctx, resolvedPath)
core/corehttp/gateway_handler_car.go
+3 -3
@@ -17,9 +17,9 @@ import (
17 "go.opentelemetry.io/otel/trace"
18 )
19
20 -// serveCar returns a CAR stream for specific DAG+selector
21 -func (i *gatewayHandler) serveCar(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, carVersion string, begin time.Time) {
22 - ctx, span := tracing.Span(r.Context(), "Gateway", "ServeCar", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
20 +// serveCAR returns a CAR stream for specific DAG+selector
21 +func (i *gatewayHandler) serveCAR(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, carVersion string, begin time.Time) {
22 + ctx, span := tracing.Span(ctx, "Gateway", "ServeCAR", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
23 defer span.End()
24 ctx, cancel := context.WithCancel(ctx)
25 defer cancel()
core/corehttp/gateway_handler_unixfs.go
+6 -5
@@ -1,6 +1,7 @@
1 package corehttp
2
3 import (
4 + "context"
5 "fmt"
6 "html"
7 "net/http"
@@ -14,8 +15,8 @@ import (
15 "go.uber.org/zap"
16 )
17
17 -func (i *gatewayHandler) serveUnixFs(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, logger *zap.SugaredLogger) {
18 - ctx, span := tracing.Span(r.Context(), "Gateway", "ServeUnixFs", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
18 +func (i *gatewayHandler) serveUnixFS(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, begin time.Time, logger *zap.SugaredLogger) {
19 + ctx, span := tracing.Span(ctx, "Gateway", "ServeUnixFS", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
20 defer span.End()
21 // Handling UnixFS
22 dr, err := i.api.Unixfs().Get(ctx, resolvedPath)
@@ -28,16 +29,16 @@ func (i *gatewayHandler) serveUnixFs(w http.ResponseWriter, r *http.Request, res
29 // Handling Unixfs file
30 if f, ok := dr.(files.File); ok {
31 logger.Debugw("serving unixfs file", "path", contentPath)
31 - i.serveFile(w, r, resolvedPath, contentPath, f, begin)
32 + i.serveFile(ctx, w, r, resolvedPath, contentPath, f, begin)
33 return
34 }
35
36 // Handling Unixfs directory
37 dir, ok := dr.(files.Directory)
38 if !ok {
38 - internalWebError(w, fmt.Errorf("unsupported UnixFs type"))
39 + internalWebError(w, fmt.Errorf("unsupported UnixFS type"))
40 return
41 }
42 logger.Debugw("serving unixfs directory", "path", contentPath)
42 - i.serveDirectory(w, r, resolvedPath, contentPath, dir, begin, logger)
43 + i.serveDirectory(ctx, w, r, resolvedPath, contentPath, dir, begin, logger)
44 }
core/corehttp/gateway_handler_unixfs_dir.go
+4 -3
@@ -1,6 +1,7 @@
1 package corehttp
2
3 import (
4 + "context"
5 "net/http"
6 "net/url"
7 gopath "path"
@@ -23,8 +24,8 @@ import (
24 // serveDirectory returns the best representation of UnixFS directory
25 //
26 // It will return index.html if present, or generate directory listing otherwise.
26 -func (i *gatewayHandler) serveDirectory(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, dir files.Directory, begin time.Time, logger *zap.SugaredLogger) {
27 - ctx, span := tracing.Span(r.Context(), "Gateway", "ServeDirectory", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
27 +func (i *gatewayHandler) serveDirectory(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, dir files.Directory, begin time.Time, logger *zap.SugaredLogger) {
28 + ctx, span := tracing.Span(ctx, "Gateway", "ServeDirectory", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
29 defer span.End()
30
31 // HostnameOption might have constructed an IPNS/IPFS path using the Host header.
@@ -69,7 +70,7 @@ func (i *gatewayHandler) serveDirectory(w http.ResponseWriter, r *http.Request,
70
71 logger.Debugw("serving index.html file", "path", idxPath)
72 // write to request
72 - i.serveFile(w, r, resolvedPath, idxPath, f, begin)
73 + i.serveFile(ctx, w, r, resolvedPath, idxPath, f, begin)
74 return
75 case resolver.ErrNoLink:
76 logger.Debugw("no index.html; noop", "path", idxPath)
core/corehttp/gateway_handler_unixfs_file.go
+3 -2
@@ -1,6 +1,7 @@
1 package corehttp
2
3 import (
4 + "context"
5 "fmt"
6 "io"
7 "mime"
@@ -19,8 +20,8 @@ import (
20
21 // serveFile returns data behind a file along with HTTP headers based on
22 // the file itself, its CID and the contentPath used for accessing it.
22 -func (i *gatewayHandler) serveFile(w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, file files.File, begin time.Time) {
23 - _, span := tracing.Span(r.Context(), "Gateway", "ServeFile", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
23 +func (i *gatewayHandler) serveFile(ctx context.Context, w http.ResponseWriter, r *http.Request, resolvedPath ipath.Resolved, contentPath ipath.Path, file files.File, begin time.Time) {
24 + _, span := tracing.Span(ctx, "Gateway", "ServeFile", trace.WithAttributes(attribute.String("path", resolvedPath.String())))
25 defer span.End()
26
27 // Set Cache-Control and read optional Last-Modified time