From 7527730d735603f0dafe14643c7d5463fc9e392b Mon Sep 17 00:00:00 2001 From: marifari-hue <241165308+marifari-hue@users.noreply.github.com> Date: Thu, 19 Feb 2026 17:09:59 +0100 Subject: [PATCH 1/6] added bodyReaderErr to req GetBody and testing --- .../otlp/otlpmetric/otlpmetrichttp/client.go | 9 +++ .../otlpmetric/otlpmetrichttp/client_test.go | 55 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/client.go b/exporters/otlp/otlpmetric/otlpmetrichttp/client.go index 76381b56ee8..ec80c5e2739 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/client.go +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/client.go @@ -236,6 +236,7 @@ func (c *client) newRequest(ctx context.Context, body []byte) (request, error) { case NoCompression: r.ContentLength = int64(len(body)) req.bodyReader = bodyReader(body) + req.GetBody = bodyReaderErr(body) case GzipCompression: // Ensure the content length is not used. r.ContentLength = -1 @@ -256,6 +257,7 @@ func (c *client) newRequest(ctx context.Context, body []byte) (request, error) { } req.bodyReader = bodyReader(b.Bytes()) + req.GetBody = bodyReaderErr(body) } return req, nil @@ -268,6 +270,13 @@ func bodyReader(buf []byte) func() io.ReadCloser { } } +// bodyReaderErr returns a closure returning a new reader for buf. +func bodyReaderErr(buf []byte) func() (io.ReadCloser, error) { + return func() (io.ReadCloser, error) { + return io.NopCloser(bytes.NewReader(buf)), nil + } +} + // request wraps an http.Request with a resettable body reader. type request struct { *http.Request diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/client_test.go b/exporters/otlp/otlpmetric/otlpmetrichttp/client_test.go index 65d7f4ccf3c..aad75cc8060 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/client_test.go +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/client_test.go @@ -8,9 +8,12 @@ import ( "crypto/tls" "errors" "fmt" + "io" "net/http" + "net/http/httptest" "net/url" "strings" + "sync" "testing" "time" @@ -314,3 +317,55 @@ func TestConfig(t *testing.T) { assert.NoError(t, exCtx.Err()) }) } + +func TestGetBodyCalledOnRedirect(t *testing.T) { + // Test that req.GetBody is set correctly, allowing the HTTP transport + // to re-send the body on 307 redirects. + var mu sync.Mutex + var requestBodies [][]byte + + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + mu.Lock() + requestBodies = append(requestBodies, body) + isFirstRequest := len(requestBodies) == 1 + mu.Unlock() + + if isFirstRequest { + w.Header().Set("Location", "/v1/metrics/final") + w.WriteHeader(http.StatusTemporaryRedirect) + return + } + + w.Header().Set("Content-Type", "application/x-protobuf") + w.WriteHeader(http.StatusOK) + }) + + server := httptest.NewServer(handler) + defer server.Close() + + opts := []Option{WithEndpoint(server.Listener.Addr().String()), WithInsecure()} + cfg := oconf.NewHTTPConfig(asHTTPOptions(opts)...) + client, err := newClient(cfg) + require.NoError(t, err) + + exporter, err := newExporter(client, cfg) + require.NoError(t, err) + ctx := t.Context() + defer func() { _ = exporter.Shutdown(ctx) }() + + err = exporter.Export(ctx, &metricdata.ResourceMetrics{}) + require.NoError(t, err) + + mu.Lock() + defer mu.Unlock() + + require.Len(t, requestBodies, 2, "expected 2 requests (original + redirect)") + assert.NotEmpty(t, requestBodies[0], "original request body should not be empty") + assert.Equal(t, requestBodies[0], requestBodies[1], "redirect body should match original") +} From c888f259b8dbbf6662e1e5c8b733b7b9e238c39a Mon Sep 17 00:00:00 2001 From: marifari-hue <241165308+marifari-hue@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:10:03 +0100 Subject: [PATCH 2/6] upodated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2943d778ec8..f9fa015ad41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ The next release will require at least [Go 1.25]. - Fix `SetAttributes` on `Record` in `go.opentelemetry.io/otel/sdk/log` to not log that attributes are dropped when they are actually not dropped. (#7662) - Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to correctly handle HTTP/2 `GOAWAY` frame. (#7794) - `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to use full path for `ioreg` command on Darwin (macOS). (#7818) +- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931) ### Deprecated From 2fadfb948f805f81223224d91525be7f91616835 Mon Sep 17 00:00:00 2001 From: marifari-hue <241165308+marifari-hue@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:14:46 +0100 Subject: [PATCH 3/6] moved the changelog line to the appropriate place --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9fa015ad41..50be69f0e86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ The next release will require at least [Go 1.25]. - Support testing of [Go 1.26]. (#7902) +### Fixed + +- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931) + @@ -49,7 +53,6 @@ The next release will require at least [Go 1.25]. - Fix `SetAttributes` on `Record` in `go.opentelemetry.io/otel/sdk/log` to not log that attributes are dropped when they are actually not dropped. (#7662) - Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to correctly handle HTTP/2 `GOAWAY` frame. (#7794) - `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to use full path for `ioreg` command on Darwin (macOS). (#7818) -- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931) ### Deprecated From 604288d25ea74dbf3f5c3db0d33c66e475a7fb2a Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Tue, 3 Mar 2026 10:15:38 +0100 Subject: [PATCH 4/6] Apply suggestions from code review --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddfa3856a2c..0962312340d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm The package contains semantic conventions from the `v1.40.0` version of the OpenTelemetry Semantic Conventions. See the [migration documentation](./semconv/v1.40.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.39.0`. (#7985) +### Fixed + +- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931) ### Removed - Drop support for [Go 1.24]. (#7984) From 646f46f67a4f0903ce2be85c6484ef5e3f5fecf9 Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Tue, 3 Mar 2026 10:16:03 +0100 Subject: [PATCH 5/6] Apply suggestion from @dmathieu --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0962312340d..e932e03a477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,6 @@ The next release will require at least [Go 1.25]. - Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#7914) - Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#7914) - Return an error when the endpoint is configured as insecure and with TLS configuration in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#7914) -- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931) ## [1.40.0/0.62.0/0.16.0] 2026-02-02 From 76d70330cf4f6c33a4e387a88e93a80d83c47623 Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Tue, 3 Mar 2026 10:16:27 +0100 Subject: [PATCH 6/6] Apply suggestion from @dmathieu --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e932e03a477..a52de51111f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixed - Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to correctly handle HTTP2 GOAWAY frame. (#7931) + ### Removed - Drop support for [Go 1.24]. (#7984)