Skip to content

Ability to access the wrapped ResponseWriter #8

Description

@pda

Thanks for the library.

It would be useful to be able to explicitly access the underlying ResponseWriter.

For example New Relic's go-agent implements their newrelic.Transaction as an extension of http.ResponseWriter. I'd like to write middleware which type-asserts txn, ok := w.(newrelic.Transaction) in order to e.g. txn.AddAttribute(). But when w is already wrapped in httpsnoop the newrelic.Transaction type-assertion fails. I guess this is a case you've described in the README as “and it won't work for applications adding their own interfaces into the mix”.

However I'd be happy to do something like this:

if snoop, ok := w.(httpsnoop.Wrapper) {
  if txn, ok := snoop.Unwrap().(newrelic.Transaction) {
    txn.SetAttribute("foo", "bar")
  }
}

This would require a method on httpsnoop's type rw e.g. rw.Unwrap() or rw.ResponseWriter(), and an interface containing that method (although the caller could be responsible for declaring the interface).

(The httpsnoop assertion may need to be recursive in case it's wrapped multiple times; e.g. a request that has passed through a logging middleware and a metrics middleware that each use httpsnoop. But that's up to the caller).

Perhaps the patch would be something like this?

--- a/codegen/main.go
+++ b/codegen/main.go
@@ -127,6 +127,14 @@ type rw struct {
        w http.ResponseWriter
        h Hooks
 }
+
+type Wrapper interface {
+       Unwrap() http.ResponseWriter
+}
+
+func (w *rw) Unwrap() http.ResponseWriter {
+       return w.w
+}
 `)
        for _, iface := range ifaces {
                for _, fn := range iface.Funcs {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions