1
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2024-12-23 22:27:38 -05:00

diagnostics: Specially handle HTTP 410 and 451 codes

An attempt to future-proof older Caddy instances so that they won't
keep trying to send telemetry to endpoints that just simply aren't
going to be available
This commit is contained in:
Matthew Holt 2018-03-21 17:51:07 -06:00
parent 4df8028bc3
commit 7c868afd32
No known key found for this signature in database
GPG key ID: 2A349DD577D586A5

View file

@ -37,6 +37,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"strconv" "strconv"
@ -83,10 +84,7 @@ func emit(final bool) error {
// terminate any pending update if this is the last one // terminate any pending update if this is the last one
if final { if final {
updateTimerMu.Lock() stopUpdateTimer()
updateTimer.Stop()
updateTimer = nil
updateTimerMu.Unlock()
} }
payloadBytes, err := makePayloadAndResetBuffer() payloadBytes, err := makePayloadAndResetBuffer()
@ -113,7 +111,37 @@ func emit(final bool) error {
continue continue
} }
// ensure we can read the response // check for any special-case response codes
if resp.StatusCode == http.StatusGone {
// the endpoint has been deprecated and is no longer servicing clients
err = fmt.Errorf("diagnostics server replied with HTTP %d; upgrade required", resp.StatusCode)
if clen := resp.Header.Get("Content-Length"); clen != "0" && clen != "" {
bodyBytes, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
log.Printf("[ERROR] Reading response body from server: %v", readErr)
}
err = fmt.Errorf("%v - %s", err, bodyBytes)
}
resp.Body.Close()
reply.Stop = true
break
}
if resp.StatusCode == http.StatusUnavailableForLegalReasons {
// the endpoint is unavailable, at least to this client, for legal reasons (!)
err = fmt.Errorf("diagnostics server replied with HTTP %d %s: please consult the project website and developers for guidance", resp.StatusCode, resp.Status)
if clen := resp.Header.Get("Content-Length"); clen != "0" && clen != "" {
bodyBytes, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
log.Printf("[ERROR] Reading response body from server: %v", readErr)
}
err = fmt.Errorf("%v - %s", err, bodyBytes)
}
resp.Body.Close()
reply.Stop = true
break
}
// okay, ensure we can interpret the response
if ct := resp.Header.Get("Content-Type"); (resp.StatusCode < 300 || resp.StatusCode >= 400) && if ct := resp.Header.Get("Content-Type"); (resp.StatusCode < 300 || resp.StatusCode >= 400) &&
!strings.Contains(ct, "json") { !strings.Contains(ct, "json") {
err = fmt.Errorf("diagnostics server replied with unknown content-type: '%s' and HTTP %s", ct, resp.Status) err = fmt.Errorf("diagnostics server replied with unknown content-type: '%s' and HTTP %s", ct, resp.Status)
@ -178,6 +206,13 @@ func emit(final bool) error {
return err return err
} }
func stopUpdateTimer() {
updateTimerMu.Lock()
updateTimer.Stop()
updateTimer = nil
updateTimerMu.Unlock()
}
// makePayloadAndResetBuffer prepares a payload // makePayloadAndResetBuffer prepares a payload
// by emptying the collection buffer. It returns // by emptying the collection buffer. It returns
// the bytes of the payload to send to the server. // the bytes of the payload to send to the server.