# Accepted status codes for this probe. Defaults to 2xx.
[ valid_status_codes: <string>, ... | default = "2xx" ]
+ # Accepted HTTP versions for this probe.
+ [ valid_http_versions: <string>, ... ]
+
# The HTTP method the probe will use.
[ method: <string> | default = "GET" ]
type HTTPProbe struct {
// Defaults to 2xx.
ValidStatusCodes []int `yaml:"valid_status_codes,omitempty"`
+ ValidHTTPVersions []string `yaml:"valid_http_versions,omitempty"`
PreferredIPProtocol string `yaml:"preferred_ip_protocol,omitempty"`
NoFollowRedirects bool `yaml:"no_follow_redirects,omitempty"`
FailIfSSL bool `yaml:"fail_if_ssl,omitempty"`
prober: http
timeout: 5s
http:
+ valid_http_versions: ["HTTP/1.1", "HTTP/2"]
valid_status_codes: [] # Defaults to 2xx
method: GET
headers:
"net/http"
"net/url"
"regexp"
+ "strconv"
"strings"
"github.com/prometheus/client_golang/prometheus"
Name: "probe_ssl_earliest_cert_expiry",
Help: "Returns earliest SSL cert expiry in unixtime",
})
+
+ probeHTTPVersionGauge = prometheus.NewGauge(prometheus.GaugeOpts{
+ Name: "probe_http_version",
+ Help: "Returns the version of HTTP of the probe response",
+ })
)
registry.MustRegister(contentLengthGauge)
registry.MustRegister(redirectsGauge)
registry.MustRegister(isSSLGauge)
registry.MustRegister(statusCodeGauge)
+ registry.MustRegister(probeHTTPVersionGauge)
httpConfig := module.HTTP
request.Body = ioutil.NopCloser(strings.NewReader(httpConfig.Body))
}
resp, err := client.Do(request)
-
// Err won't be nil if redirects were turned off. See https://github.com/golang/go/issues/3795
if err != nil && resp == nil {
log.Warnf("Error for HTTP request to %s: %s", target, err)
if success && (len(httpConfig.FailIfMatchesRegexp) > 0 || len(httpConfig.FailIfNotMatchesRegexp) > 0) {
success = matchRegularExpressions(resp.Body, httpConfig)
}
+
+ var httpVersionNumber float64
+ httpVersionNumber, err = strconv.ParseFloat(strings.TrimPrefix(resp.Proto, "HTTP/"), 64)
+ if err != nil {
+ log.Errorf("Error parsing version number from HTTP version: %v", err)
+ }
+ probeHTTPVersionGauge.Set(httpVersionNumber)
+
+ if len(httpConfig.ValidHTTPVersions) != 0 {
+ found := false
+ for _, version := range httpConfig.ValidHTTPVersions {
+ if version == resp.Proto {
+ found = true
+ break
+ }
+ }
+ if !found {
+ success = false
+ }
+ }
+
}
if resp == nil {
}
}
+func TestValidHTTPVersion(t *testing.T) {
+ tests := []struct {
+ ValidHTTPVersions []string
+ ShouldSucceed bool
+ }{
+ {[]string{}, true},
+ {[]string{"HTTP/1.1"}, true},
+ {[]string{"HTTP/1.1", "HTTP/2"}, true},
+ {[]string{"HTTP/2"}, false},
+ }
+ for i, test := range tests {
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ }))
+ defer ts.Close()
+ recorder := httptest.NewRecorder()
+ registry := prometheus.NewRegistry()
+ result := probeHTTP(ts.URL,
+ Module{Timeout: time.Second, HTTP: HTTPProbe{
+ ValidHTTPVersions: test.ValidHTTPVersions,
+ }}, registry)
+ body := recorder.Body.String()
+ if result != test.ShouldSucceed {
+ t.Fatalf("Test %v had unexpected result: %s", i, body)
+ }
+ }
+}
+
func TestRedirectFollowed(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" {