69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
package probers
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/letsencrypt/boulder/observer/obsdialer"
|
|
)
|
|
|
|
// HTTPProbe is the exported 'Prober' object for monitors configured to
|
|
// perform HTTP requests.
|
|
type HTTPProbe struct {
|
|
url string
|
|
rcodes []int
|
|
useragent string
|
|
insecure bool
|
|
}
|
|
|
|
// Name returns a string that uniquely identifies the monitor.
|
|
|
|
func (p HTTPProbe) Name() string {
|
|
insecure := ""
|
|
if p.insecure {
|
|
insecure = "-insecure"
|
|
}
|
|
return fmt.Sprintf("%s-%d-%s%s", p.url, p.rcodes, p.useragent, insecure)
|
|
}
|
|
|
|
// Kind returns a name that uniquely identifies the `Kind` of `Prober`.
|
|
func (p HTTPProbe) Kind() string {
|
|
return "HTTP"
|
|
}
|
|
|
|
// isExpected ensures that the received HTTP response code matches one
|
|
// that's expected.
|
|
func (p HTTPProbe) isExpected(received int) bool {
|
|
for _, c := range p.rcodes {
|
|
if received == c {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Probe performs the configured HTTP request.
|
|
func (p HTTPProbe) Probe(timeout time.Duration) (bool, time.Duration) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
client := http.Client{
|
|
Transport: &http.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: p.insecure},
|
|
DialContext: obsdialer.Dialer.DialContext,
|
|
}}
|
|
req, err := http.NewRequestWithContext(ctx, "GET", p.url, nil)
|
|
if err != nil {
|
|
return false, 0
|
|
}
|
|
req.Header.Set("User-Agent", p.useragent)
|
|
start := time.Now()
|
|
// TODO(@beautifulentropy): add support for more than HTTP GET
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return false, time.Since(start)
|
|
}
|
|
return p.isExpected(resp.StatusCode), time.Since(start)
|
|
}
|