diff --git a/main.go b/main.go index 40082fc47..81d639404 100644 --- a/main.go +++ b/main.go @@ -120,20 +120,12 @@ func probeHandler(w http.ResponseWriter, r *http.Request, c *config.Config, logg return } - if module.Prober == "http" { - paramHost := params.Get("hostname") - if paramHost != "" { - if module.HTTP.Headers == nil { - module.HTTP.Headers = make(map[string]string) - } else { - for name, value := range module.HTTP.Headers { - if strings.Title(name) == "Host" && value != paramHost { - http.Error(w, fmt.Sprintf("Host header defined both in module configuration (%s) and with parameter 'hostname' (%s)", value, paramHost), http.StatusBadRequest) - return - } - } - } - module.HTTP.Headers["Host"] = paramHost + hostname := params.Get("hostname") + if module.Prober == "http" && hostname != "" { + err = setHttpHost(hostname, &module) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return } } @@ -167,6 +159,23 @@ func probeHandler(w http.ResponseWriter, r *http.Request, c *config.Config, logg h.ServeHTTP(w, r) } +func setHttpHost(hostname string, module *config.Module) error { + // By creating a new hashmap and copying values there we + // ensure that the initial configuration remain intact. + headers := make(map[string]string) + if module.HTTP.Headers != nil { + for name, value := range module.HTTP.Headers { + if strings.Title(name) == "Host" && value != hostname { + return fmt.Errorf("host header defined both in module configuration (%s) and with URL-parameter 'hostname' (%s)", value, hostname) + } + headers[name] = value + } + } + headers["Host"] = hostname + module.HTTP.Headers = headers + return nil +} + type scrapeLogger struct { next log.Logger buffer bytes.Buffer diff --git a/prober/http.go b/prober/http.go index d88d5d2e7..41c8398c2 100644 --- a/prober/http.go +++ b/prober/http.go @@ -341,20 +341,18 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr httpClientConfig := module.HTTP.HTTPClientConfig if len(httpClientConfig.TLSConfig.ServerName) == 0 { - // If there is no `server_name` in tls_config it makes - // sense to use the host header value to avoid possible - // TLS handshake problems. - changed := false + // If there is no `server_name` in tls_config, use + // the hostname of the target. + httpClientConfig.TLSConfig.ServerName = targetHost + + // However, if there is a Host header it is better to use + // its value instead. This helps avoid TLS handshake error + // if targetHost is an IP address. for name, value := range httpConfig.Headers { if strings.Title(name) == "Host" { httpClientConfig.TLSConfig.ServerName = value - changed = true } } - if !changed { - // Otherwise use the hostname of the target. - httpClientConfig.TLSConfig.ServerName = targetHost - } } client, err := pconfig.NewClientFromConfig(httpClientConfig, "http_probe", pconfig.WithKeepAlivesDisabled()) if err != nil {