489 lines
23 KiB
Diff
489 lines
23 KiB
Diff
|
|
From a17c5cebb633b15b67d42b3f94d4bb5db3f06164 Mon Sep 17 00:00:00 2001
|
||
|
|
From: jxy_git <jiangxinyu@kylinos.cn>
|
||
|
|
Date: Thu, 9 Jan 2025 09:52:11 +0800
|
||
|
|
Subject: [PATCH] Fix CVE-2022-21698
|
||
|
|
|
||
|
|
Reference: https://github.com/prometheus/client_golang/commit/9075cdf61646b5adf54d3ba77a0e4f6c65cb4fd7
|
||
|
|
|
||
|
|
---
|
||
|
|
.../prometheus/promhttp/instrument_client.go | 28 ++-
|
||
|
|
.../prometheus/promhttp/instrument_server.go | 160 ++++++++++++------
|
||
|
|
.../prometheus/promhttp/option.go | 27 +++
|
||
|
|
.../prometheus/promhttp/option_test.go | 55 ++++++
|
||
|
|
4 files changed, 213 insertions(+), 57 deletions(-)
|
||
|
|
create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
|
||
|
|
create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/option_test.go
|
||
|
|
|
||
|
|
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
|
||
|
|
index 83c49b6..5f9dca3 100644
|
||
|
|
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
|
||
|
|
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
|
||
|
|
@@ -49,7 +49,10 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
|
||
|
|
// http.RoundTripper to observe the request result with the provided CounterVec.
|
||
|
|
// The CounterVec must have zero, one, or two non-const non-curried labels. For
|
||
|
|
// those, the only allowed label names are "code" and "method". The function
|
||
|
|
-// panics otherwise. Partitioning of the CounterVec happens by HTTP status code
|
||
|
|
+// panics otherwise. For the "method" label a predefined default label value set
|
||
|
|
+// is used to filter given values. Values besides predefined values will count
|
||
|
|
+// as `unknown` method.`WithExtraMethods` can be used to add more
|
||
|
|
+// methods to the set. Partitioning of the CounterVec happens by HTTP status code
|
||
|
|
// and/or HTTP method if the respective instance label names are present in the
|
||
|
|
// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
|
||
|
|
//
|
||
|
|
@@ -57,13 +60,18 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
|
||
|
|
// is not incremented.
|
||
|
|
//
|
||
|
|
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
|
||
|
|
-func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc {
|
||
|
|
+func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
|
||
|
|
+ rtOpts := &option{}
|
||
|
|
+ for _, o := range opts {
|
||
|
|
+ o(rtOpts)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
code, method := checkLabels(counter)
|
||
|
|
|
||
|
|
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||
|
|
resp, err := next.RoundTrip(r)
|
||
|
|
if err == nil {
|
||
|
|
- counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
|
||
|
|
+ counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Inc()
|
||
|
|
}
|
||
|
|
return resp, err
|
||
|
|
})
|
||
|
|
@@ -73,7 +81,10 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou
|
||
|
|
// http.RoundTripper to observe the request duration with the provided
|
||
|
|
// ObserverVec. The ObserverVec must have zero, one, or two non-const
|
||
|
|
// non-curried labels. For those, the only allowed label names are "code" and
|
||
|
|
-// "method". The function panics otherwise. The Observe method of the Observer
|
||
|
|
+// "method". The function panics otherwise. For the "method" label a predefined
|
||
|
|
+// default label value set is used to filter given values. Values besides
|
||
|
|
+// predefined values will count as `unknown` method. `WithExtraMethods`
|
||
|
|
+// can be used to add more methods to the set. The Observe method of the Observer
|
||
|
|
// in the ObserverVec is called with the request duration in
|
||
|
|
// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
|
||
|
|
// respective instance label names are present in the ObserverVec. For
|
||
|
|
@@ -85,14 +96,19 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou
|
||
|
|
//
|
||
|
|
// Note that this method is only guaranteed to never observe negative durations
|
||
|
|
// if used with Go1.9+.
|
||
|
|
-func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc {
|
||
|
|
+func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
|
||
|
|
+ rtOpts := &option{}
|
||
|
|
+ for _, o := range opts {
|
||
|
|
+ o(rtOpts)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
code, method := checkLabels(obs)
|
||
|
|
|
||
|
|
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||
|
|
start := time.Now()
|
||
|
|
resp, err := next.RoundTrip(r)
|
||
|
|
if err == nil {
|
||
|
|
- obs.With(labels(code, method, r.Method, resp.StatusCode)).Observe(time.Since(start).Seconds())
|
||
|
|
+ obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Observe(time.Since(start).Seconds())
|
||
|
|
}
|
||
|
|
return resp, err
|
||
|
|
})
|
||
|
|
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
|
||
|
|
index 9db2438..9842e5f 100644
|
||
|
|
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
|
||
|
|
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
|
||
|
|
@@ -58,7 +58,12 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
|
||
|
|
//
|
||
|
|
// Note that this method is only guaranteed to never observe negative durations
|
||
|
|
// if used with Go1.9+.
|
||
|
|
-func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
|
||
|
|
+func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||
|
|
+ mwOpts := &option{}
|
||
|
|
+ for _, o := range opts {
|
||
|
|
+ o(mwOpts)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
code, method := checkLabels(obs)
|
||
|
|
|
||
|
|
if code {
|
||
|
|
@@ -67,57 +72,70 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht
|
||
|
|
d := newDelegator(w, nil)
|
||
|
|
next.ServeHTTP(d, r)
|
||
|
|
|
||
|
|
- obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
|
||
|
|
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
now := time.Now()
|
||
|
|
next.ServeHTTP(w, r)
|
||
|
|
- obs.With(labels(code, method, r.Method, 0)).Observe(time.Since(now).Seconds())
|
||
|
|
+ obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// InstrumentHandlerCounter is a middleware that wraps the provided http.Handler
|
||
|
|
-// to observe the request result with the provided CounterVec. The CounterVec
|
||
|
|
-// must have zero, one, or two non-const non-curried labels. For those, the only
|
||
|
|
-// allowed label names are "code" and "method". The function panics
|
||
|
|
-// otherwise. Partitioning of the CounterVec happens by HTTP status code and/or
|
||
|
|
-// HTTP method if the respective instance label names are present in the
|
||
|
|
-// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
|
||
|
|
+// to observe the request result with the provided CounterVec. The CounterVec
|
||
|
|
+// must have valid metric and label names and must have zero, one, or two
|
||
|
|
+// non-const non-curried labels. For those, the only allowed label names are
|
||
|
|
+// "code" and "method". The function panics otherwise. For the "method"
|
||
|
|
+// label a predefined default label value set is used to filter given values.
|
||
|
|
+// Values besides predefined values will count as `unknown` method.
|
||
|
|
+// `WithExtraMethods` can be used to add more methods to the set. Partitioning of the
|
||
|
|
+// CounterVec happens by HTTP status code and/or HTTP method if the respective
|
||
|
|
+// instance label names are present in the CounterVec. For unpartitioned
|
||
|
|
+// counting, use a CounterVec with zero labels.
|
||
|
|
//
|
||
|
|
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
|
||
|
|
//
|
||
|
|
// If the wrapped Handler panics, the Counter is not incremented.
|
||
|
|
//
|
||
|
|
// See the example for InstrumentHandlerDuration for example usage.
|
||
|
|
-func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
|
||
|
|
+func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||
|
|
+ mwOpts := &option{}
|
||
|
|
+ for _, o := range opts {
|
||
|
|
+ o(mwOpts)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
code, method := checkLabels(counter)
|
||
|
|
|
||
|
|
if code {
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
d := newDelegator(w, nil)
|
||
|
|
next.ServeHTTP(d, r)
|
||
|
|
- counter.With(labels(code, method, r.Method, d.Status())).Inc()
|
||
|
|
+ counter.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Inc()
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
next.ServeHTTP(w, r)
|
||
|
|
- counter.With(labels(code, method, r.Method, 0)).Inc()
|
||
|
|
+ counter.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Inc()
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
|
||
|
|
// http.Handler to observe with the provided ObserverVec the request duration
|
||
|
|
-// until the response headers are written. The ObserverVec must have zero, one,
|
||
|
|
-// or two non-const non-curried labels. For those, the only allowed label names
|
||
|
|
-// are "code" and "method". The function panics otherwise. The Observe method of
|
||
|
|
-// the Observer in the ObserverVec is called with the request duration in
|
||
|
|
-// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
|
||
|
|
-// respective instance label names are present in the ObserverVec. For
|
||
|
|
-// unpartitioned observations, use an ObserverVec with zero labels. Note that
|
||
|
|
-// partitioning of Histograms is expensive and should be used judiciously.
|
||
|
|
+// until the response headers are written. The ObserverVec must have valid
|
||
|
|
+// metric and label names and must have zero, one, or two non-const non-curried
|
||
|
|
+// labels. For those, the only allowed label names are "code" and "method". The
|
||
|
|
+// function panics otherwise. For the "method" label a predefined default label
|
||
|
|
+// value set is used to filter given values. Values besides predefined values
|
||
|
|
+// will count as `unknown` method.`WithExtraMethods` can be used to add more
|
||
|
|
+// methods to the set. The Observe method of the Observer in the
|
||
|
|
+// ObserverVec is called with the request duration in seconds. Partitioning
|
||
|
|
+// happens by HTTP status code and/or HTTP method if the respective instance
|
||
|
|
+// label names are present in the ObserverVec. For unpartitioned observations,
|
||
|
|
+// use an ObserverVec with zero labels. Note that partitioning of Histograms is
|
||
|
|
+// expensive and should be used judiciously.
|
||
|
|
//
|
||
|
|
// If the wrapped Handler panics before calling WriteHeader, no value is
|
||
|
|
// reported.
|
||
|
|
@@ -126,35 +144,48 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler)
|
||
|
|
// if used with Go1.9+.
|
||
|
|
//
|
||
|
|
// See the example for InstrumentHandlerDuration for example usage.
|
||
|
|
-func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
|
||
|
|
+func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||
|
|
+ mwOpts := &option{}
|
||
|
|
+ for _, o := range opts {
|
||
|
|
+ o(mwOpts)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
code, method := checkLabels(obs)
|
||
|
|
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
now := time.Now()
|
||
|
|
d := newDelegator(w, func(status int) {
|
||
|
|
- obs.With(labels(code, method, r.Method, status)).Observe(time.Since(now).Seconds())
|
||
|
|
+ obs.With(labels(code, method, r.Method, status, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||
|
|
})
|
||
|
|
next.ServeHTTP(d, r)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// InstrumentHandlerRequestSize is a middleware that wraps the provided
|
||
|
|
-// http.Handler to observe the request size with the provided ObserverVec. The
|
||
|
|
-// ObserverVec must have zero, one, or two non-const non-curried labels. For
|
||
|
|
-// those, the only allowed label names are "code" and "method". The function
|
||
|
|
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
|
||
|
|
-// called with the request size in bytes. Partitioning happens by HTTP status
|
||
|
|
-// code and/or HTTP method if the respective instance label names are present in
|
||
|
|
-// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero
|
||
|
|
-// labels. Note that partitioning of Histograms is expensive and should be used
|
||
|
|
-// judiciously.
|
||
|
|
+// http.Handler to observe the request size with the provided ObserverVec. The
|
||
|
|
+// ObserverVec must have valid metric and label names and must have zero, one,
|
||
|
|
+// or two non-const non-curried labels. For those, the only allowed label names
|
||
|
|
+// are "code" and "method". The function panics otherwise. For the "method"
|
||
|
|
+// label a predefined default label value set is used to filter given values.
|
||
|
|
+// Values besides predefined values will count as `unknown` method.
|
||
|
|
+// `WithExtraMethods` can be used to add more methods to the set. The Observe
|
||
|
|
+// method of the Observer in the ObserverVec is called with the request size in
|
||
|
|
+// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
|
||
|
|
+// respective instance label names are present in the ObserverVec. For
|
||
|
|
+// unpartitioned observations, use an ObserverVec with zero labels. Note that
|
||
|
|
+// partitioning of Histograms is expensive and should be used judiciously.
|
||
|
|
//
|
||
|
|
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
|
||
|
|
//
|
||
|
|
// If the wrapped Handler panics, no values are reported.
|
||
|
|
//
|
||
|
|
// See the example for InstrumentHandlerDuration for example usage.
|
||
|
|
-func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
|
||
|
|
+func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||
|
|
+ mwOpts := &option{}
|
||
|
|
+ for _, o := range opts {
|
||
|
|
+ o(mwOpts)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
code, method := checkLabels(obs)
|
||
|
|
|
||
|
|
if code {
|
||
|
|
@@ -162,39 +193,48 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
|
||
|
|
d := newDelegator(w, nil)
|
||
|
|
next.ServeHTTP(d, r)
|
||
|
|
size := computeApproximateRequestSize(r)
|
||
|
|
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
|
||
|
|
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(size))
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
next.ServeHTTP(w, r)
|
||
|
|
size := computeApproximateRequestSize(r)
|
||
|
|
- obs.With(labels(code, method, r.Method, 0)).Observe(float64(size))
|
||
|
|
+ obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(float64(size))
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// InstrumentHandlerResponseSize is a middleware that wraps the provided
|
||
|
|
-// http.Handler to observe the response size with the provided ObserverVec. The
|
||
|
|
-// ObserverVec must have zero, one, or two non-const non-curried labels. For
|
||
|
|
-// those, the only allowed label names are "code" and "method". The function
|
||
|
|
-// panics otherwise. The Observe method of the Observer in the ObserverVec is
|
||
|
|
-// called with the response size in bytes. Partitioning happens by HTTP status
|
||
|
|
-// code and/or HTTP method if the respective instance label names are present in
|
||
|
|
-// the ObserverVec. For unpartitioned observations, use an ObserverVec with zero
|
||
|
|
-// labels. Note that partitioning of Histograms is expensive and should be used
|
||
|
|
-// judiciously.
|
||
|
|
+// http.Handler to observe the response size with the provided ObserverVec. The
|
||
|
|
+// ObserverVec must have valid metric and label names and must have zero, one,
|
||
|
|
+// or two non-const non-curried labels. For those, the only allowed label names
|
||
|
|
+// are "code" and "method". The function panics otherwise. For the "method"
|
||
|
|
+// label a predefined default label value set is used to filter given values.
|
||
|
|
+// Values besides predefined values will count as `unknown` method.
|
||
|
|
+// `WithExtraMethods` can be used to add more methods to the set. The Observe
|
||
|
|
+// method of the Observer in the ObserverVec is called with the response size in
|
||
|
|
+// bytes. Partitioning happens by HTTP status code and/or HTTP method if the
|
||
|
|
+// respective instance label names are present in the ObserverVec. For
|
||
|
|
+// unpartitioned observations, use an ObserverVec with zero labels. Note that
|
||
|
|
+// partitioning of Histograms is expensive and should be used judiciously.
|
||
|
|
//
|
||
|
|
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
|
||
|
|
//
|
||
|
|
// If the wrapped Handler panics, no values are reported.
|
||
|
|
//
|
||
|
|
// See the example for InstrumentHandlerDuration for example usage.
|
||
|
|
-func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
|
||
|
|
+func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler {
|
||
|
|
+ mwOpts := &option{}
|
||
|
|
+ for _, o := range opts {
|
||
|
|
+ o(mwOpts)
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
code, method := checkLabels(obs)
|
||
|
|
+
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
d := newDelegator(w, nil)
|
||
|
|
next.ServeHTTP(d, r)
|
||
|
|
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
|
||
|
|
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(d.Written()))
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -279,7 +319,7 @@ func isLabelCurried(c prometheus.Collector, label string) bool {
|
||
|
|
// unnecessary allocations on each request.
|
||
|
|
var emptyLabels = prometheus.Labels{}
|
||
|
|
|
||
|
|
-func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
|
||
|
|
+func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels {
|
||
|
|
if !(code || method) {
|
||
|
|
return emptyLabels
|
||
|
|
}
|
||
|
|
@@ -289,7 +329,7 @@ func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
|
||
|
|
labels["code"] = sanitizeCode(status)
|
||
|
|
}
|
||
|
|
if method {
|
||
|
|
- labels["method"] = sanitizeMethod(reqMethod)
|
||
|
|
+ labels["method"] = sanitizeMethod(reqMethod, extraMethods...)
|
||
|
|
}
|
||
|
|
|
||
|
|
return labels
|
||
|
|
@@ -319,7 +359,12 @@ func computeApproximateRequestSize(r *http.Request) int {
|
||
|
|
return s
|
||
|
|
}
|
||
|
|
|
||
|
|
-func sanitizeMethod(m string) string {
|
||
|
|
+// If the wrapped http.Handler has a known method, it will be sanitized and returned.
|
||
|
|
+// Otherwise, "unknown" will be returned. The known method list can be extended
|
||
|
|
+// as needed by using extraMethods parameter.
|
||
|
|
+func sanitizeMethod(m string, extraMethods ...string) string {
|
||
|
|
+ // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for
|
||
|
|
+ // the methods chosen as default.
|
||
|
|
switch m {
|
||
|
|
case "GET", "get":
|
||
|
|
return "get"
|
||
|
|
@@ -337,15 +382,25 @@ func sanitizeMethod(m string) string {
|
||
|
|
return "options"
|
||
|
|
case "NOTIFY", "notify":
|
||
|
|
return "notify"
|
||
|
|
+ case "TRACE", "trace":
|
||
|
|
+ return "trace"
|
||
|
|
+ case "PATCH", "patch":
|
||
|
|
+ return "patch"
|
||
|
|
default:
|
||
|
|
- return strings.ToLower(m)
|
||
|
|
+ for _, method := range extraMethods {
|
||
|
|
+ if strings.EqualFold(m, method) {
|
||
|
|
+ return strings.ToLower(m)
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ return "unknown"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// If the wrapped http.Handler has not set a status code, i.e. the value is
|
||
|
|
-// currently 0, santizeCode will return 200, for consistency with behavior in
|
||
|
|
+// currently 0, sanitizeCode will return 200, for consistency with behavior in
|
||
|
|
// the stdlib.
|
||
|
|
func sanitizeCode(s int) string {
|
||
|
|
+ // See for accepted codes https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||
|
|
switch s {
|
||
|
|
case 100:
|
||
|
|
return "100"
|
||
|
|
@@ -442,6 +497,9 @@ func sanitizeCode(s int) string {
|
||
|
|
return "511"
|
||
|
|
|
||
|
|
default:
|
||
|
|
- return strconv.Itoa(s)
|
||
|
|
+ if s >= 100 && s <= 599 {
|
||
|
|
+ return strconv.Itoa(s)
|
||
|
|
+ }
|
||
|
|
+ return "unknown"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
|
||
|
|
new file mode 100644
|
||
|
|
index 0000000..2fddb59
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
|
||
|
|
@@ -0,0 +1,27 @@
|
||
|
|
+// Copyright 2022 The Prometheus Authors
|
||
|
|
+// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
+// you may not use this file except in compliance with the License.
|
||
|
|
+// You may obtain a copy of the License at
|
||
|
|
+//
|
||
|
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
+//
|
||
|
|
+// Unless required by applicable law or agreed to in writing, software
|
||
|
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
+// See the License for the specific language governing permissions and
|
||
|
|
+// limitations under the License.
|
||
|
|
+package promhttp
|
||
|
|
+// Option are used to configure a middleware or round tripper..
|
||
|
|
+type Option func(*option)
|
||
|
|
+type option struct {
|
||
|
|
+ extraMethods []string
|
||
|
|
+}
|
||
|
|
+// WithExtraMethods adds additional HTTP methods to the list of allowed methods.
|
||
|
|
+// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list.
|
||
|
|
+//
|
||
|
|
+// See the example for ExampleInstrumentHandlerWithExtraMethods for example usage.
|
||
|
|
+func WithExtraMethods(methods ...string) Option {
|
||
|
|
+ return func(o *option) {
|
||
|
|
+ o.extraMethods = methods
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
\ No newline at end of file
|
||
|
|
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option_test.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option_test.go
|
||
|
|
new file mode 100644
|
||
|
|
index 0000000..44a2c19
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option_test.go
|
||
|
|
@@ -0,0 +1,55 @@
|
||
|
|
+// Copyright 2022 The Prometheus Authors
|
||
|
|
+// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
+// you may not use this file except in compliance with the License.
|
||
|
|
+// You may obtain a copy of the License at
|
||
|
|
+//
|
||
|
|
+// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
+//
|
||
|
|
+// Unless required by applicable law or agreed to in writing, software
|
||
|
|
+// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
+// See the License for the specific language governing permissions and
|
||
|
|
+// limitations under the License.
|
||
|
|
+package promhttp
|
||
|
|
+import (
|
||
|
|
+ "log"
|
||
|
|
+ "net/http"
|
||
|
|
+ "github.com/prometheus/client_golang/prometheus"
|
||
|
|
+)
|
||
|
|
+func ExampleInstrumentHandlerWithExtraMethods() {
|
||
|
|
+ counter := prometheus.NewCounterVec(
|
||
|
|
+ prometheus.CounterOpts{
|
||
|
|
+ Name: "api_requests_total",
|
||
|
|
+ Help: "A counter for requests to the wrapped handler.",
|
||
|
|
+ },
|
||
|
|
+ []string{"code", "method"},
|
||
|
|
+ )
|
||
|
|
+ // duration is partitioned by the HTTP method and handler. It uses custom
|
||
|
|
+ // buckets based on the expected request duration.
|
||
|
|
+ duration := prometheus.NewHistogramVec(
|
||
|
|
+ prometheus.HistogramOpts{
|
||
|
|
+ Name: "request_duration_seconds",
|
||
|
|
+ Help: "A histogram of latencies for requests.",
|
||
|
|
+ Buckets: []float64{.25, .5, 1, 2.5, 5, 10},
|
||
|
|
+ },
|
||
|
|
+ []string{"handler", "method"},
|
||
|
|
+ )
|
||
|
|
+ // Create the handlers that will be wrapped by the middleware.
|
||
|
|
+ pullHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
+ w.Write([]byte("Pull"))
|
||
|
|
+ })
|
||
|
|
+ // Specify additional HTTP methods to be added to the label allow list.
|
||
|
|
+ opts := WithExtraMethods("CUSTOM_METHOD")
|
||
|
|
+ // Instrument the handlers with all the metrics, injecting the "handler"
|
||
|
|
+ // label by currying.
|
||
|
|
+ pullChain :=
|
||
|
|
+ InstrumentHandlerDuration(duration.MustCurryWith(prometheus.Labels{"handler": "pull"}),
|
||
|
|
+ InstrumentHandlerCounter(counter, pullHandler, opts),
|
||
|
|
+ opts,
|
||
|
|
+ )
|
||
|
|
+ http.Handle("/metrics", Handler())
|
||
|
|
+ http.Handle("/pull", pullChain)
|
||
|
|
+ if err := http.ListenAndServe(":3000", nil); err != nil {
|
||
|
|
+ log.Fatal(err)
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
\ No newline at end of file
|
||
|
|
--
|
||
|
|
2.43.0
|
||
|
|
|