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