go-sdk
go-sdk copied to clipboard
http: superfluous response.WriteHeader call (v1.3.0)
Describe the bug In version 1.3.0, I get the following message at startup. But it was not in v1.2.0.
http: superfluous response.WriteHeader call from github.com/dapr/go-sdk/service/http.(*Server).registerBaseHandler.func3 (topic.go:60)
It seems that the function I need is working. But could you please check why getting the message?
To Reproduce The following is the sample code.
package main
import (
"context"
"log"
"os/signal"
"syscall"
"time"
"net/http"
"os"
"github.com/dapr/go-sdk/service/common"
daprd "github.com/dapr/go-sdk/service/http"
flag "github.com/spf13/pflag"
)
var (
logger = log.New(os.Stdout, "", 0)
address string
wait int
)
func main() {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
logger.Printf("Starting...")
flag.StringVarP(&address, "address", "a", ":8080", "set ip:port of this app")
flag.IntVarP(&wait, "wait", "w", 0, "set wait seconds after getting signal for testing")
flag.Parse()
s := daprd.NewService(address)
if err := s.AddBindingInvocationHandler("/cron", cronHandler); err != nil {
logger.Fatalf("Error adding binding handler: %v", err)
}
go func() {
<-ctx.Done()
logger.Printf("Got signal. shutting down...")
for i := 0; i < wait; i++ {
time.Sleep(1 * time.Second)
logger.Printf("Waited for %d seconds...", i+1)
}
s.Stop()
}()
go func() {
for {
logger.Printf("I'm awake.")
time.Sleep(1 * time.Minute)
}
}()
if err := s.Start(); err != nil && err != http.ErrServerClosed {
logger.Fatalf("Error starting service: %v", err)
}
logger.Printf("Exit.")
}
func cronHandler(ctx context.Context, in *common.BindingEvent) (out []byte, err error) {
logger.Printf("Got cron event.")
return nil, nil
}
Expected behavior Startup without the message.
Seems this line can be removed: https://github.com/dapr/go-sdk/blob/v1.3.0/service/http/topic.go#L60
Refer to: https://pkg.go.dev/net/http#ResponseWriter
// Write writes the data to the connection as part of an HTTP reply.
//
// If WriteHeader has not yet been called, Write calls
// WriteHeader(http.StatusOK) before writing the data. If the Header
// does not contain a Content-Type line, Write adds a Content-Type set
// to the result of passing the initial 512 bytes of written data to
// DetectContentType. Additionally, if the total size of all written
// data is under a few KB and there are no Flush calls, the
// Content-Length header is added automatically.
//
// Depending on the HTTP protocol version and the client, calling
// Write or WriteHeader may prevent future reads on the
// Request.Body. For HTTP/1.x requests, handlers should read any
// needed request body data before writing the response. Once the
// headers have been flushed (due to either an explicit Flusher.Flush
// call or writing enough data to trigger a flush), the request body
// may be unavailable. For HTTP/2 requests, the Go HTTP server permits
// handlers to continue to read the request body while concurrently
// writing the response. However, such behavior may not be supported
// by all HTTP/2 clients. Handlers should read before writing if
// possible to maximize compatibility.
Write([]byte) (int, error)
Write will call WriteHeader(http.StatusOK) automatically, so no need to explicitly call WriteHeader(http.StatusOK).
https://github.com/dapr/go-sdk/pull/227
Can this issue be closed?