Skip to content

Commit 2e15df2

Browse files
committed
otelhttp: Ignore informational header when persisting status
Signed-off-by: Janusz Marcinkiewicz <[email protected]>
1 parent 3ea6585 commit 2e15df2

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (w *RespWriterWrapper) Write(p []byte) (int, error) {
6161

6262
// WriteHeader persists initial statusCode for span attribution.
6363
// All calls to WriteHeader will be propagated to the underlying ResponseWriter
64-
// and will persist the statusCode from the first call.
64+
// and will persist the statusCode from the first call (except for informational headers).
6565
// Blocking consecutive calls to WriteHeader alters expected behavior and will
6666
// remove warning logs from net/http where developers will notice incorrect handler implementations.
6767
func (w *RespWriterWrapper) WriteHeader(statusCode int) {
@@ -77,9 +77,17 @@ func (w *RespWriterWrapper) WriteHeader(statusCode int) {
7777
// parent method.
7878
func (w *RespWriterWrapper) writeHeader(statusCode int) {
7979
if !w.wroteHeader {
80+
// Ignore informational headers.
81+
// Based on https://github.com/golang/go/blob/go1.24.1/src/net/http/server.go#L1216
82+
if statusCode >= 100 && statusCode <= 199 && statusCode != http.StatusSwitchingProtocols {
83+
goto propagate
84+
}
85+
8086
w.wroteHeader = true
8187
w.statusCode = statusCode
8288
}
89+
90+
propagate:
8391
w.ResponseWriter.WriteHeader(statusCode)
8492
}
8593

instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ func TestRespWriterWriteHeader(t *testing.T) {
2525
assert.Equal(t, http.StatusTeapot, rw.statusCode)
2626
}
2727

28+
func TestRespWriterWriteInformationalHeader(t *testing.T) {
29+
rw := NewRespWriterWrapper(&httptest.ResponseRecorder{}, func(int64) {})
30+
31+
rw.WriteHeader(http.StatusContinue)
32+
assert.Equal(t, http.StatusOK, rw.statusCode)
33+
assert.False(t, rw.wroteHeader)
34+
35+
rw.WriteHeader(http.StatusGone)
36+
assert.Equal(t, http.StatusGone, rw.statusCode)
37+
assert.True(t, rw.wroteHeader)
38+
}
39+
2840
func TestRespWriterFlush(t *testing.T) {
2941
rw := NewRespWriterWrapper(&httptest.ResponseRecorder{}, func(int64) {})
3042

0 commit comments

Comments
 (0)