Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error logs coming for http: superfluous response.WriteHeader call when using otelhttp handler and http.Flusher interface #6073

Closed
niallnsec opened this issue Sep 4, 2024 · 5 comments · Fixed by #6074
Labels
area: instrumentation Related to an instrumentation package bug Something isn't working instrumentation: otelhttp
Milestone

Comments

@niallnsec
Copy link

Description

Same bug as #6053 which has not been fixed fully. When using the Flusher interface, for example for SSE, the bug still manifests.

Environment

  • OS: macOS
  • Architecture: arm64
  • Go Version: 1.23.0
  • otelhttp version: main (06ace3e)

Steps To Reproduce

  1. Using this code:
package main

import (
	"fmt"
	"net/http"
	"strings"
	"time"

	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)

func main() {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		flusher, ok := w.(http.Flusher)
		if !ok {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		w.Header().Set("Content-Type", "text/event-stream")
		w.Header().Set("Cache-Control", "no-cache")
		w.Header().Set("Connection", "keep-alive")

		t := time.NewTicker(time.Second * 10)
		defer t.Stop()

		_, err := w.Write(formatSSE("ping", ""))
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		flusher.Flush()

		for {
			select {
			case <-r.Context().Done():
				return
			case <-t.C:
				_, err := w.Write(formatSSE("ping", ""))
				if err != nil {
					w.WriteHeader(http.StatusInternalServerError)
					return
				}
				flusher.Flush()
			}
		}
		w.WriteHeader(http.StatusOK)
		w.Write([]byte("Hello, World!"))
	})

	otelHandler := otelhttp.NewHandler(handler, "simple-server")

	server := http.Server{
		Addr:    ":8080",
		Handler: otelHandler,
	}

	if err := server.ListenAndServe(); http.ErrServerClosed != err {
		fmt.Printf("Error: %v\n", err)
	}

	fmt.Println("Server stopped")
}

func formatSSE(event string, data string) []byte {
	eventPayload := "event: " + event + "\n"
	dataLines := strings.Split(data, "\n")
	for _, line := range dataLines {
		eventPayload = eventPayload + "data: " + line + "\n"
	}
	return []byte(eventPayload + "\n")
}
  1. Run:
go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@main

go run main.go

curl http://localhost:8080
  1. See error ... (Sent for each SSE event sent to the client)
2024/09/04 12:27:52 http: superfluous response.WriteHeader call from go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request.(*RespWriterWrapper).writeHeader (resp_writer_wrapper.go:80)

Expected behavior

No output

@niallnsec niallnsec added area: instrumentation Related to an instrumentation package bug Something isn't working instrumentation: otelhttp labels Sep 4, 2024
@dmathieu
Copy link
Member

dmathieu commented Sep 4, 2024

Duplicate of #6053

@dmathieu dmathieu marked this as a duplicate of #6053 Sep 4, 2024
@dmathieu dmathieu closed this as completed Sep 4, 2024
@niallnsec
Copy link
Author

@dmathieu #6053 is closed but the issue is not fixed as stated in that issue, this is not a duplicate.

@niallnsec
Copy link
Author

The issue specifically relates to the case when the http.Flusher interface is used, which was not accounted for in the fix for #6053 hence the new report.

My report above gives you a reproducible demonstration of this bug using the lates commit of this repository, not the last release, confirming that the issue is not fixed by 54d6916.

Please re-open this issue.

@amanakin
Copy link
Contributor

amanakin commented Sep 4, 2024

I think we just can add the same check as #6053 here:
https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go#L85

@dmathieu dmathieu reopened this Sep 4, 2024
@dmathieu
Copy link
Member

dmathieu commented Sep 4, 2024

My bad, sorry. Feel free to open a PR with the fix and a test case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: instrumentation Related to an instrumentation package bug Something isn't working instrumentation: otelhttp
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants