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 }