Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 

369 linhas
11 KiB

  1. // Copyright 2017 The Prometheus Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package promhttp
  14. import (
  15. "bufio"
  16. "io"
  17. "net"
  18. "net/http"
  19. )
  20. const (
  21. closeNotifier = 1 << iota
  22. flusher
  23. hijacker
  24. readerFrom
  25. pusher
  26. )
  27. type delegator interface {
  28. http.ResponseWriter
  29. Status() int
  30. Written() int64
  31. }
  32. type responseWriterDelegator struct {
  33. http.ResponseWriter
  34. status int
  35. written int64
  36. wroteHeader bool
  37. observeWriteHeader func(int)
  38. }
  39. func (r *responseWriterDelegator) Status() int {
  40. return r.status
  41. }
  42. func (r *responseWriterDelegator) Written() int64 {
  43. return r.written
  44. }
  45. func (r *responseWriterDelegator) WriteHeader(code int) {
  46. if r.observeWriteHeader != nil && !r.wroteHeader {
  47. // Only call observeWriteHeader for the 1st time. It's a bug if
  48. // WriteHeader is called more than once, but we want to protect
  49. // against it here. Note that we still delegate the WriteHeader
  50. // to the original ResponseWriter to not mask the bug from it.
  51. r.observeWriteHeader(code)
  52. }
  53. r.status = code
  54. r.wroteHeader = true
  55. r.ResponseWriter.WriteHeader(code)
  56. }
  57. func (r *responseWriterDelegator) Write(b []byte) (int, error) {
  58. // If applicable, call WriteHeader here so that observeWriteHeader is
  59. // handled appropriately.
  60. if !r.wroteHeader {
  61. r.WriteHeader(http.StatusOK)
  62. }
  63. n, err := r.ResponseWriter.Write(b)
  64. r.written += int64(n)
  65. return n, err
  66. }
  67. type closeNotifierDelegator struct{ *responseWriterDelegator }
  68. type flusherDelegator struct{ *responseWriterDelegator }
  69. type hijackerDelegator struct{ *responseWriterDelegator }
  70. type readerFromDelegator struct{ *responseWriterDelegator }
  71. type pusherDelegator struct{ *responseWriterDelegator }
  72. func (d closeNotifierDelegator) CloseNotify() <-chan bool {
  73. //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.
  74. return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
  75. }
  76. func (d flusherDelegator) Flush() {
  77. // If applicable, call WriteHeader here so that observeWriteHeader is
  78. // handled appropriately.
  79. if !d.wroteHeader {
  80. d.WriteHeader(http.StatusOK)
  81. }
  82. d.ResponseWriter.(http.Flusher).Flush()
  83. }
  84. func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  85. return d.ResponseWriter.(http.Hijacker).Hijack()
  86. }
  87. func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
  88. // If applicable, call WriteHeader here so that observeWriteHeader is
  89. // handled appropriately.
  90. if !d.wroteHeader {
  91. d.WriteHeader(http.StatusOK)
  92. }
  93. n, err := d.ResponseWriter.(io.ReaderFrom).ReadFrom(re)
  94. d.written += n
  95. return n, err
  96. }
  97. func (d pusherDelegator) Push(target string, opts *http.PushOptions) error {
  98. return d.ResponseWriter.(http.Pusher).Push(target, opts)
  99. }
  100. var pickDelegator = make([]func(*responseWriterDelegator) delegator, 32)
  101. func init() {
  102. // TODO(beorn7): Code generation would help here.
  103. pickDelegator[0] = func(d *responseWriterDelegator) delegator { // 0
  104. return d
  105. }
  106. pickDelegator[closeNotifier] = func(d *responseWriterDelegator) delegator { // 1
  107. return closeNotifierDelegator{d}
  108. }
  109. pickDelegator[flusher] = func(d *responseWriterDelegator) delegator { // 2
  110. return flusherDelegator{d}
  111. }
  112. pickDelegator[flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 3
  113. return struct {
  114. *responseWriterDelegator
  115. http.Flusher
  116. http.CloseNotifier
  117. }{d, flusherDelegator{d}, closeNotifierDelegator{d}}
  118. }
  119. pickDelegator[hijacker] = func(d *responseWriterDelegator) delegator { // 4
  120. return hijackerDelegator{d}
  121. }
  122. pickDelegator[hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 5
  123. return struct {
  124. *responseWriterDelegator
  125. http.Hijacker
  126. http.CloseNotifier
  127. }{d, hijackerDelegator{d}, closeNotifierDelegator{d}}
  128. }
  129. pickDelegator[hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 6
  130. return struct {
  131. *responseWriterDelegator
  132. http.Hijacker
  133. http.Flusher
  134. }{d, hijackerDelegator{d}, flusherDelegator{d}}
  135. }
  136. pickDelegator[hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 7
  137. return struct {
  138. *responseWriterDelegator
  139. http.Hijacker
  140. http.Flusher
  141. http.CloseNotifier
  142. }{d, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
  143. }
  144. pickDelegator[readerFrom] = func(d *responseWriterDelegator) delegator { // 8
  145. return readerFromDelegator{d}
  146. }
  147. pickDelegator[readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 9
  148. return struct {
  149. *responseWriterDelegator
  150. io.ReaderFrom
  151. http.CloseNotifier
  152. }{d, readerFromDelegator{d}, closeNotifierDelegator{d}}
  153. }
  154. pickDelegator[readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 10
  155. return struct {
  156. *responseWriterDelegator
  157. io.ReaderFrom
  158. http.Flusher
  159. }{d, readerFromDelegator{d}, flusherDelegator{d}}
  160. }
  161. pickDelegator[readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 11
  162. return struct {
  163. *responseWriterDelegator
  164. io.ReaderFrom
  165. http.Flusher
  166. http.CloseNotifier
  167. }{d, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
  168. }
  169. pickDelegator[readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 12
  170. return struct {
  171. *responseWriterDelegator
  172. io.ReaderFrom
  173. http.Hijacker
  174. }{d, readerFromDelegator{d}, hijackerDelegator{d}}
  175. }
  176. pickDelegator[readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 13
  177. return struct {
  178. *responseWriterDelegator
  179. io.ReaderFrom
  180. http.Hijacker
  181. http.CloseNotifier
  182. }{d, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
  183. }
  184. pickDelegator[readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 14
  185. return struct {
  186. *responseWriterDelegator
  187. io.ReaderFrom
  188. http.Hijacker
  189. http.Flusher
  190. }{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
  191. }
  192. pickDelegator[readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 15
  193. return struct {
  194. *responseWriterDelegator
  195. io.ReaderFrom
  196. http.Hijacker
  197. http.Flusher
  198. http.CloseNotifier
  199. }{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
  200. }
  201. pickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16
  202. return pusherDelegator{d}
  203. }
  204. pickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17
  205. return struct {
  206. *responseWriterDelegator
  207. http.Pusher
  208. http.CloseNotifier
  209. }{d, pusherDelegator{d}, closeNotifierDelegator{d}}
  210. }
  211. pickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18
  212. return struct {
  213. *responseWriterDelegator
  214. http.Pusher
  215. http.Flusher
  216. }{d, pusherDelegator{d}, flusherDelegator{d}}
  217. }
  218. pickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19
  219. return struct {
  220. *responseWriterDelegator
  221. http.Pusher
  222. http.Flusher
  223. http.CloseNotifier
  224. }{d, pusherDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
  225. }
  226. pickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20
  227. return struct {
  228. *responseWriterDelegator
  229. http.Pusher
  230. http.Hijacker
  231. }{d, pusherDelegator{d}, hijackerDelegator{d}}
  232. }
  233. pickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21
  234. return struct {
  235. *responseWriterDelegator
  236. http.Pusher
  237. http.Hijacker
  238. http.CloseNotifier
  239. }{d, pusherDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
  240. }
  241. pickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22
  242. return struct {
  243. *responseWriterDelegator
  244. http.Pusher
  245. http.Hijacker
  246. http.Flusher
  247. }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
  248. }
  249. pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23
  250. return struct {
  251. *responseWriterDelegator
  252. http.Pusher
  253. http.Hijacker
  254. http.Flusher
  255. http.CloseNotifier
  256. }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
  257. }
  258. pickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24
  259. return struct {
  260. *responseWriterDelegator
  261. http.Pusher
  262. io.ReaderFrom
  263. }{d, pusherDelegator{d}, readerFromDelegator{d}}
  264. }
  265. pickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25
  266. return struct {
  267. *responseWriterDelegator
  268. http.Pusher
  269. io.ReaderFrom
  270. http.CloseNotifier
  271. }{d, pusherDelegator{d}, readerFromDelegator{d}, closeNotifierDelegator{d}}
  272. }
  273. pickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26
  274. return struct {
  275. *responseWriterDelegator
  276. http.Pusher
  277. io.ReaderFrom
  278. http.Flusher
  279. }{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}}
  280. }
  281. pickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27
  282. return struct {
  283. *responseWriterDelegator
  284. http.Pusher
  285. io.ReaderFrom
  286. http.Flusher
  287. http.CloseNotifier
  288. }{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
  289. }
  290. pickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28
  291. return struct {
  292. *responseWriterDelegator
  293. http.Pusher
  294. io.ReaderFrom
  295. http.Hijacker
  296. }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}}
  297. }
  298. pickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29
  299. return struct {
  300. *responseWriterDelegator
  301. http.Pusher
  302. io.ReaderFrom
  303. http.Hijacker
  304. http.CloseNotifier
  305. }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}
  306. }
  307. pickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30
  308. return struct {
  309. *responseWriterDelegator
  310. http.Pusher
  311. io.ReaderFrom
  312. http.Hijacker
  313. http.Flusher
  314. }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}
  315. }
  316. pickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31
  317. return struct {
  318. *responseWriterDelegator
  319. http.Pusher
  320. io.ReaderFrom
  321. http.Hijacker
  322. http.Flusher
  323. http.CloseNotifier
  324. }{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}
  325. }
  326. }
  327. func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
  328. d := &responseWriterDelegator{
  329. ResponseWriter: w,
  330. observeWriteHeader: observeWriteHeaderFunc,
  331. }
  332. id := 0
  333. //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.
  334. if _, ok := w.(http.CloseNotifier); ok {
  335. id += closeNotifier
  336. }
  337. if _, ok := w.(http.Flusher); ok {
  338. id += flusher
  339. }
  340. if _, ok := w.(http.Hijacker); ok {
  341. id += hijacker
  342. }
  343. if _, ok := w.(io.ReaderFrom); ok {
  344. id += readerFrom
  345. }
  346. if _, ok := w.(http.Pusher); ok {
  347. id += pusher
  348. }
  349. return pickDelegator[id](d)
  350. }