github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/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 "github.com/hxx258456/ccgo/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  }