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