github.com/lulzWill/go-agent@v2.1.2+incompatible/internal_response_writer.go (about)

     1  package newrelic
     2  
     3  import (
     4  	"bufio"
     5  	"io"
     6  	"net"
     7  	"net/http"
     8  )
     9  
    10  const (
    11  	hasC = 1 << iota // CloseNotifier
    12  	hasF             // Flusher
    13  	hasH             // Hijacker
    14  	hasR             // ReaderFrom
    15  )
    16  
    17  type wrap struct{ *txn }
    18  type wrapR struct{ *txn }
    19  type wrapH struct{ *txn }
    20  type wrapHR struct{ *txn }
    21  type wrapF struct{ *txn }
    22  type wrapFR struct{ *txn }
    23  type wrapFH struct{ *txn }
    24  type wrapFHR struct{ *txn }
    25  type wrapC struct{ *txn }
    26  type wrapCR struct{ *txn }
    27  type wrapCH struct{ *txn }
    28  type wrapCHR struct{ *txn }
    29  type wrapCF struct{ *txn }
    30  type wrapCFR struct{ *txn }
    31  type wrapCFH struct{ *txn }
    32  type wrapCFHR struct{ *txn }
    33  
    34  func (x wrapC) CloseNotify() <-chan bool    { return x.W.(http.CloseNotifier).CloseNotify() }
    35  func (x wrapCR) CloseNotify() <-chan bool   { return x.W.(http.CloseNotifier).CloseNotify() }
    36  func (x wrapCH) CloseNotify() <-chan bool   { return x.W.(http.CloseNotifier).CloseNotify() }
    37  func (x wrapCHR) CloseNotify() <-chan bool  { return x.W.(http.CloseNotifier).CloseNotify() }
    38  func (x wrapCF) CloseNotify() <-chan bool   { return x.W.(http.CloseNotifier).CloseNotify() }
    39  func (x wrapCFR) CloseNotify() <-chan bool  { return x.W.(http.CloseNotifier).CloseNotify() }
    40  func (x wrapCFH) CloseNotify() <-chan bool  { return x.W.(http.CloseNotifier).CloseNotify() }
    41  func (x wrapCFHR) CloseNotify() <-chan bool { return x.W.(http.CloseNotifier).CloseNotify() }
    42  
    43  func (x wrapF) Flush()    { x.W.(http.Flusher).Flush() }
    44  func (x wrapFR) Flush()   { x.W.(http.Flusher).Flush() }
    45  func (x wrapFH) Flush()   { x.W.(http.Flusher).Flush() }
    46  func (x wrapFHR) Flush()  { x.W.(http.Flusher).Flush() }
    47  func (x wrapCF) Flush()   { x.W.(http.Flusher).Flush() }
    48  func (x wrapCFR) Flush()  { x.W.(http.Flusher).Flush() }
    49  func (x wrapCFH) Flush()  { x.W.(http.Flusher).Flush() }
    50  func (x wrapCFHR) Flush() { x.W.(http.Flusher).Flush() }
    51  
    52  func (x wrapH) Hijack() (net.Conn, *bufio.ReadWriter, error)    { return x.W.(http.Hijacker).Hijack() }
    53  func (x wrapHR) Hijack() (net.Conn, *bufio.ReadWriter, error)   { return x.W.(http.Hijacker).Hijack() }
    54  func (x wrapFH) Hijack() (net.Conn, *bufio.ReadWriter, error)   { return x.W.(http.Hijacker).Hijack() }
    55  func (x wrapFHR) Hijack() (net.Conn, *bufio.ReadWriter, error)  { return x.W.(http.Hijacker).Hijack() }
    56  func (x wrapCH) Hijack() (net.Conn, *bufio.ReadWriter, error)   { return x.W.(http.Hijacker).Hijack() }
    57  func (x wrapCHR) Hijack() (net.Conn, *bufio.ReadWriter, error)  { return x.W.(http.Hijacker).Hijack() }
    58  func (x wrapCFH) Hijack() (net.Conn, *bufio.ReadWriter, error)  { return x.W.(http.Hijacker).Hijack() }
    59  func (x wrapCFHR) Hijack() (net.Conn, *bufio.ReadWriter, error) { return x.W.(http.Hijacker).Hijack() }
    60  
    61  func (x wrapR) ReadFrom(r io.Reader) (int64, error)    { return x.W.(io.ReaderFrom).ReadFrom(r) }
    62  func (x wrapHR) ReadFrom(r io.Reader) (int64, error)   { return x.W.(io.ReaderFrom).ReadFrom(r) }
    63  func (x wrapFR) ReadFrom(r io.Reader) (int64, error)   { return x.W.(io.ReaderFrom).ReadFrom(r) }
    64  func (x wrapFHR) ReadFrom(r io.Reader) (int64, error)  { return x.W.(io.ReaderFrom).ReadFrom(r) }
    65  func (x wrapCR) ReadFrom(r io.Reader) (int64, error)   { return x.W.(io.ReaderFrom).ReadFrom(r) }
    66  func (x wrapCHR) ReadFrom(r io.Reader) (int64, error)  { return x.W.(io.ReaderFrom).ReadFrom(r) }
    67  func (x wrapCFR) ReadFrom(r io.Reader) (int64, error)  { return x.W.(io.ReaderFrom).ReadFrom(r) }
    68  func (x wrapCFHR) ReadFrom(r io.Reader) (int64, error) { return x.W.(io.ReaderFrom).ReadFrom(r) }
    69  
    70  func upgradeTxn(txn *txn) Transaction {
    71  	x := 0
    72  	if _, ok := txn.W.(http.CloseNotifier); ok {
    73  		x |= hasC
    74  	}
    75  	if _, ok := txn.W.(http.Flusher); ok {
    76  		x |= hasF
    77  	}
    78  	if _, ok := txn.W.(http.Hijacker); ok {
    79  		x |= hasH
    80  	}
    81  	if _, ok := txn.W.(io.ReaderFrom); ok {
    82  		x |= hasR
    83  	}
    84  
    85  	switch x {
    86  	default:
    87  		// Wrap the transaction even when there are no methods needed to
    88  		// ensure consistent error stack trace depth.
    89  		return wrap{txn}
    90  	case hasR:
    91  		return wrapR{txn}
    92  	case hasH:
    93  		return wrapH{txn}
    94  	case hasH | hasR:
    95  		return wrapHR{txn}
    96  	case hasF:
    97  		return wrapF{txn}
    98  	case hasF | hasR:
    99  		return wrapFR{txn}
   100  	case hasF | hasH:
   101  		return wrapFH{txn}
   102  	case hasF | hasH | hasR:
   103  		return wrapFHR{txn}
   104  	case hasC:
   105  		return wrapC{txn}
   106  	case hasC | hasR:
   107  		return wrapCR{txn}
   108  	case hasC | hasH:
   109  		return wrapCH{txn}
   110  	case hasC | hasH | hasR:
   111  		return wrapCHR{txn}
   112  	case hasC | hasF:
   113  		return wrapCF{txn}
   114  	case hasC | hasF | hasR:
   115  		return wrapCFR{txn}
   116  	case hasC | hasF | hasH:
   117  		return wrapCFH{txn}
   118  	case hasC | hasF | hasH | hasR:
   119  		return wrapCFHR{txn}
   120  	}
   121  }