go-sdk icon indicating copy to clipboard operation
go-sdk copied to clipboard

http: superfluous response.WriteHeader call (v1.3.0)

Open torumakabe opened this issue 4 years ago • 3 comments

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.

torumakabe avatar Nov 15 '21 05:11 torumakabe

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).

tpiperatgod avatar Nov 15 '21 06:11 tpiperatgod

https://github.com/dapr/go-sdk/pull/227

daixiang0 avatar Dec 13 '21 07:12 daixiang0

Can this issue be closed?

sicoyle avatar Sep 08 '23 19:09 sicoyle