Repository: go
Issue: x/net/webdav: `WriteHeader` may be called twice when webdav processes methods such as `PROPFIND`
Labels: NeedsInvestigation

### Go version

go version go1.21.6 darwin/arm64

### Output of `go env` in your module/workspace:

```shell
GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/myself/Library/Caches/go-build'
GOENV='/Users/myself/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/myself/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/myself/go'
GOPRIVATE=''
GOPROXY='https://goproxy.cn,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.6'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/myself/Desktop/webdav/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/7k/jrqj5sv161n2sy70g9st76_40000gn/T/go-build1299288959=/tmp/go-build -gno-record-gcc-switches -fno-common'
```


### What did you do?

I tried to modify http request method from `HEAD` to `PROPFIND` so that I can mock the `PROPFIND` request. As follows:
```go
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method == "HEAD" {
		r.Method = "PROPFIND"
		if r.Header.Get("Depth") == "" {
			r.Header.Add("Depth", "0")
		}
	}
	handler := &webdav.Handler{
		FileSystem:  myFileSystem,
                 LockSystem: webdav.NewMemLS(),
	}
	handler.ServeHTTP(w, r)
}
```
I realize that it is not a right approach after testing. 
But I got a confusing error message `http: superfluous response.WriteHeader call from github.com/hacdias/webdav/v4/lib.responseWriterNoBody.WriteHeader (webdav.go:222)`:
<img width="593" alt="image" src="https://github.com/golang/go/assets/28889103/d7334396-6b23-4e67-a928-49ab1a7a1c2d">
And my webdav client received a `207` response:
<img width="296" alt="image" src="https://github.com/golang/go/assets/28889103/e846c791-822d-44ce-b8f3-96e5122173c1">


### What did you see happen?

 I got a confusing error message `http: superfluous response.WriteHeader call from github.com/hacdias/webdav/v4/lib.responseWriterNoBody.WriteHeader (webdav.go:222)` and `207` response.
I tried to debug the code, I found that I would get an `short write` error in this `handlePropfind` function
<img width="867" alt="image" src="https://github.com/golang/go/assets/28889103/50189cfa-2432-4b40-a7ca-4dec745e0ab5">
</br></br>
But before triggering this error, the status code of `207` had already been written into the response header:
<img width="1406" alt="image" src="https://github.com/golang/go/assets/28889103/4ac64ab9-9964-497c-bb22-5c997eec567a">
</br></br>
So in the outermost function used to handle `PROPFIND` or `PROPPATCH` methods, when a `status` with `err` was returned, the `WriteHeader` was called again, resulting in the client receive a `207` response and the server side get an `superfluous response.WriteHeader call` error.
<img width="980" alt="image" src="https://github.com/golang/go/assets/28889103/ed5370e4-e981-4f48-aaab-4eda62055420">


### What did you expect to see?

I have given up using `head` to simulate `propfind`, but I hope that when processing the `PROPFIND` or `PROPPATCH` methods, if the server side encounters an error, it can return `500` instead of `207`