Skip to content

net/http/httptest: ResponseRecorder does not mimic real behavior of WriteHeader() #8857

@scottferg

Description

@scottferg
httptest.ResponseRecorder does not mimic the behavior of the net/http package when
headers are written after a call to WriteHeader().

Per the documentation for http.ResponseWriter:

    Header returns the header map that will be sent by WriteHeader.
    Changing the header after a call to WriteHeader (or Write) has
    no effect.

However, if you change the header after a call to WriteHeader while using
httptest.ResponseRecorder the result will appear as though the header was set (and sent)
correctly. 

This appears to be caused by the fact that in this function:

// Header returns the response headers.
func (rw *ResponseRecorder) Header() http.Header {
        m := rw.HeaderMap
        if m == nil {
                m = make(http.Header)
                rw.HeaderMap = m
        }
        return m
}

there is no check to see if rw.wroteHeader is true. Anything set before or after
`rw.wroteHeader = true` will still show up in this map.


What steps reproduce the problem?
If possible, include a link to a program on play.golang.org.

1. In an http.HandlerFunc, call rw.Header().Set("Some-Header",
"Some-Value") after a call to rw.WriteHeader(statuscode)
2. Call this handler by passing in an httptest.ResponseRecorder

What happened?

recorder.HeaderMap["Some-Header"][0] will be set to "Some-Value"

What should have happened instead?

"Some-Header" should not have been set

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions