TUN-6248: Fix panic in cloudflared during tracing when origin doesn't provide header map

This commit is contained in:
João Oliveirinha 2022-05-18 11:11:48 +01:00
parent 4b6437cc60
commit 26a7b59f6f
3 changed files with 30 additions and 0 deletions

View File

@ -203,6 +203,11 @@ func (p *Proxy) proxyHTTPRequest(
tracing.EndWithStatus(ttfbSpan, codes.Ok, resp.Status) tracing.EndWithStatus(ttfbSpan, codes.Ok, resp.Status)
defer resp.Body.Close() defer resp.Body.Close()
// resp headers can be nil
if resp.Header == nil {
resp.Header = make(http.Header)
}
// Add spans to response header (if available) // Add spans to response header (if available)
tr.AddSpans(resp.Header, p.log) tr.AddSpans(resp.Header, p.log)

View File

@ -103,6 +103,11 @@ func (cft *TracedRequest) Tracer() trace.Tracer {
// Spans returns the spans as base64 encoded protobuf otlp traces. // Spans returns the spans as base64 encoded protobuf otlp traces.
func (cft *TracedRequest) AddSpans(headers http.Header, log *zerolog.Logger) { func (cft *TracedRequest) AddSpans(headers http.Header, log *zerolog.Logger) {
if headers == nil {
log.Error().Msgf("provided headers map is nil")
return
}
enc, err := cft.exporter.Spans() enc, err := cft.exporter.Spans()
switch err { switch err {
case nil: case nil:
@ -121,6 +126,7 @@ func (cft *TracedRequest) AddSpans(headers http.Header, log *zerolog.Logger) {
log.Error().Msgf("no traces provided and no error from exporter") log.Error().Msgf("no traces provided and no error from exporter")
return return
} }
headers[CanonicalCloudflaredTracingHeader] = []string{enc} headers[CanonicalCloudflaredTracingHeader] = []string{enc}
} }

View File

@ -1,13 +1,16 @@
package tracing package tracing
import ( import (
"context"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
tracesdk "go.opentelemetry.io/otel/sdk/trace" tracesdk "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
) )
func TestNewCfTracer(t *testing.T) { func TestNewCfTracer(t *testing.T) {
@ -48,3 +51,19 @@ func TestNewCfTracerInvalidHeaders(t *testing.T) {
assert.IsType(t, &NoopOtlpClient{}, tr.exporter) assert.IsType(t, &NoopOtlpClient{}, tr.exporter)
} }
} }
func TestAddingSpansWithNilMap(t *testing.T) {
req := httptest.NewRequest("GET", "http://localhost", nil)
req.Header.Add(TracerContextName, "14cb070dde8e51fc5ae8514e69ba42ca:b38f1bf5eae406f3:0:1")
tr := NewTracedRequest(req)
exporter := tr.exporter.(*InMemoryOtlpClient)
// add fake spans
spans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})
err := exporter.UploadTraces(context.Background(), spans)
assert.NoError(t, err)
// a panic shouldn't occur
tr.AddSpans(nil, &zerolog.Logger{})
}