Status is always equals 0 with proxy

Hi,

I’m working on a Datadog plugin, but I’m facind a weird issue. all request forwarded to a proxy give a status = 0 and error = nil even if, in the browser, I get a 200 and the right page displayed.

demo.local:80 {
  tls off

  header / -Server

  proxy / 127.0.0.1:9090 {
    transparent
  }

  datadog {
    statsd 127.0.0.1:8125
    tags sandbox caddy
    rate 1.0
  }

  log /tmp/caddy-access-demo.log {
    rotate_size 10
    rotate_age  30
    rotate_keep 5
  }

  errors /tmp/caddy-error-demo.log {
    rotate_size 10
    rotate_age  30
    rotate_keep 5
  }
}

Here the handler:

func (datadog DatadogModule) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) (int, error) {
	rw := httpserver.NewResponseRecorder(responseWriter)
	status, err := datadog.Next.ServeHTTP(rw, request)

    fmt.Println(status) // Print 0
    fmt.Println(err) // Print nill

	switch status / 100 {
	case 1:
		glDatadogMetrics.response1xxCount += 1
		break
	case 2:
		glDatadogMetrics.response2xxCount += 1
		break
	case 3:
		glDatadogMetrics.response3xxCount += 1
		break
	case 4:
		glDatadogMetrics.response4xxCount += 1
		break
	default:
		glDatadogMetrics.response5xxCount += 1
		break
	}
	return status, err
}

Hey Thibault,

Read the godoc for httpserver.Handler carefully:

Handler is like http.Handler except ServeHTTP may return a status code and/or error.

If ServeHTTP writes the response header, it should return a status code of 0. This signals to other handlers before it that the response is already handled, and that they should not write to it also. Keep in mind that writing to the response body writes the header, too.

If ServeHTTP encounters an error, it should return the error value so it can be logged by designated error-handling middleware.

If writing a response after calling the next ServeHTTP method, the returned status code SHOULD be used when writing the response.

If handling errors after calling the next ServeHTTP method, the returned error value SHOULD be logged or handled accordingly.

Otherwise, return values should be propagated down the middleware chain by returning them unchanged.

It looks like what you want is a type that records the written status code (various middlewares do this, for example, log, errors, etc.) – the return type is only for control flow of the handlers.