I guess we'll disagree about whether eliminating a global variable [in a multi-threaded language] is nothing more than "might feel a bit nicer". Same with using a class which specifically exists for testing.
net/http works fine with a response interface:
context := newContext(req)
response := chain.yield(context)
// the exact same code you had:
for k, v := range response.Header() {
w.Header()[k] = v
}
...
This has the added benefit of letting you use different response implementations. A streaming implementation, an in-memory implementation, or, probably the most important if you're doing high traffic, one that relies on a pre-allocated byte-pool.
EDIT: Sorry, not trying to be negative (so sick of this on here), but I do think global variables are really, really bad and we probably shouldn't be promoting patterns that rely on them.
Sure, I didn't say it was impossible to convert your proposed Response type to a proper net/http response when you need it.
But, like I said and you just demonstrated, glue code is needed to do that. That makes people write differing middleware application mechanisms that are incompatible with each other.
Sure, ResponseRecorder is placed in net/http/httptest and that makes sense. But then again, nothing in the actual implementation is integrated with the testing package or tied to testing in general. IMO there's nothing that makes it unsuitable for other usage. It's a simple buffer to accumulate HTTP, that's it. Even if one were to implement a buffering writer like that on their own, it wouldn't differ too much.
net/http works fine with a response interface:
This has the added benefit of letting you use different response implementations. A streaming implementation, an in-memory implementation, or, probably the most important if you're doing high traffic, one that relies on a pre-allocated byte-pool.A little nitpick on the side, new(sync.RWMutex) isn't needed. You can just do var cmMutex sync.RWMutex (http://golang.org/src/pkg/net/http/server.go?s=45646:46651#L...)
EDIT: Sorry, not trying to be negative (so sick of this on here), but I do think global variables are really, really bad and we probably shouldn't be promoting patterns that rely on them.