Skip to content

Commit 7f6e47d

Browse files
committed
otelhttp: Remove custom wrapper after handling request
Signed-off-by: Janusz Marcinkiewicz <[email protected]>
1 parent 3ea6585 commit 7f6e47d

File tree

5 files changed

+32
-0
lines changed

5 files changed

+32
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1111
### Changed
1212

1313
- Jaeger remote sampler's probabilistic strategy now uses the same sampling algorithm as `trace.TraceIDRatioBased` in `go.opentelemetry.io/contrib/samplers/jaegerremote`. (#6892)
14+
- Remove the custom body wrapper from the request's body after the request is processed to allow body type comparisons with the original type in `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` and `go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux`. (#6914)
1415

1516
### Removed
1617

instrumentation/github.com/gorilla/mux/otelmux/mux.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,12 @@ func (tw traceware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
138138
// ReadCloser fulfills a certain interface and it is indeed nil or NoBody.
139139
bw := request.NewBodyWrapper(r.Body, readRecordFunc)
140140
if r.Body != nil && r.Body != http.NoBody {
141+
prevBody := r.Body
141142
r.Body = bw
143+
144+
// Restore the original body after the request is processed to avoid issues
145+
// with extra wrapper since `http/server.go` later checks type of `r.Body`.
146+
defer func() { r.Body = prevBody }()
142147
}
143148

144149
writeRecordFunc := func(int64) {}

instrumentation/github.com/gorilla/mux/otelmux/mux_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/gorilla/mux"
1717
"github.com/stretchr/testify/assert"
1818

19+
"go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux/internal/request"
1920
"go.opentelemetry.io/otel"
2021
"go.opentelemetry.io/otel/propagation"
2122
"go.opentelemetry.io/otel/trace"
@@ -28,6 +29,23 @@ var sc = trace.NewSpanContext(trace.SpanContextConfig{
2829
TraceFlags: trace.FlagsSampled,
2930
})
3031

32+
func TestRequestBodyWrapper(t *testing.T) {
33+
router := mux.NewRouter()
34+
router.Use(Middleware("foobar"))
35+
router.HandleFunc("/user/{id}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
36+
w.WriteHeader(http.StatusOK)
37+
}))
38+
39+
r := httptest.NewRequest("POST", "/user/123", strings.NewReader(`{"name":"John Doe","age":30}`))
40+
r = r.WithContext(trace.ContextWithRemoteSpanContext(context.Background(), sc))
41+
w := httptest.NewRecorder()
42+
43+
router.ServeHTTP(w, r)
44+
45+
_, ok := r.Body.(*request.BodyWrapper)
46+
assert.Falsef(t, ok, "body should not be wrapped after request is processed")
47+
}
48+
3149
func TestPassthroughSpanFromGlobalTracer(t *testing.T) {
3250
var called bool
3351
router := mux.NewRouter()

instrumentation/net/http/otelhttp/handler.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,12 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
140140
// ReadCloser fulfills a certain interface and it is indeed nil or NoBody.
141141
bw := request.NewBodyWrapper(r.Body, readRecordFunc)
142142
if r.Body != nil && r.Body != http.NoBody {
143+
prevBody := r.Body
143144
r.Body = bw
145+
146+
// Restore the original body after the request is processed to avoid issues
147+
// with extra wrapper since `http/server.go` later checks type of `r.Body`.
148+
defer func() { r.Body = prevBody }()
144149
}
145150

146151
writeRecordFunc := func(int64) {}

instrumentation/net/http/otelhttp/handler_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/stretchr/testify/assert"
1818
"github.com/stretchr/testify/require"
1919

20+
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request"
2021
"go.opentelemetry.io/otel/attribute"
2122
"go.opentelemetry.io/otel/codes"
2223
"go.opentelemetry.io/otel/propagation"
@@ -99,6 +100,8 @@ func TestHandler(t *testing.T) {
99100
rr := httptest.NewRecorder()
100101
tc.handler(t).ServeHTTP(rr, r)
101102
assert.Equal(t, tc.expectedStatusCode, rr.Result().StatusCode) //nolint:bodyclose // False positive for httptest.ResponseRecorder: https://github.com/timakin/bodyclose/issues/59.
103+
_, ok := r.Body.(*request.BodyWrapper)
104+
assert.Falsef(t, ok, "body should not be wrapped after request is processed")
102105
})
103106
}
104107
}

0 commit comments

Comments
 (0)