diff --git a/acme/client.go b/acme/client.go index d3fb6223..76fe7066 100644 --- a/acme/client.go +++ b/acme/client.go @@ -121,9 +121,8 @@ func (c *Client) Register() (*RegistrationResource, error) { } defer resp.Body.Close() - if resp.StatusCode == http.StatusConflict { - // REVIEW: should this return an error? - return nil, errors.New("This account is already registered with this CA.") + if resp.StatusCode >= http.StatusBadRequest { + return nil, handleHTTPError(resp) } var serverReg Registration @@ -167,7 +166,7 @@ func (c *Client) AgreeToTOS() error { defer resp.Body.Close() if resp.StatusCode != http.StatusAccepted { - return fmt.Errorf("The server returned %d but we expected %d", resp.StatusCode, http.StatusAccepted) + return handleHTTPError(resp) } return nil @@ -216,9 +215,8 @@ func (c *Client) RevokeCertificate(certificate []byte) error { } defer resp.Body.Close() - if resp.StatusCode != 200 { - body, _ := ioutil.ReadAll(resp.Body) - return fmt.Errorf("The server returned an error while trying to revoke the certificate.\n%s", body) + if resp.StatusCode != http.StatusOK { + return handleHTTPError(resp) } return nil @@ -369,8 +367,7 @@ func (c *Client) getChallenges(domains []string) []*authorizationResource { } if resp.StatusCode != http.StatusCreated { - errc <- fmt.Errorf("Getting challenges for %s failed. Got status %d but expected %d", - domain, resp.StatusCode, http.StatusCreated) + errc <- handleHTTPError(resp) } links := parseLinks(resp.Header["Link"]) @@ -523,7 +520,7 @@ func (c *Client) requestCertificate(authz *authorizationResource, result chan Ce break default: - logger().Printf("[%s] The server returned an unexpected status code %d.", authz.Domain, resp.StatusCode) + errc <- handleHTTPError(resp) return } diff --git a/acme/error.go b/acme/error.go new file mode 100644 index 00000000..86a87cae --- /dev/null +++ b/acme/error.go @@ -0,0 +1,30 @@ +package acme + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// Error asdf +type Error struct { + StatusCode int `json:"status,omitempty"` + Type string `json:"type"` + Detail string `json:"detail"` +} + +func (e Error) Error() string { + return fmt.Sprintf("[%d] Type: %s Detail: %s", e.StatusCode, e.Type, e.Detail) +} + +func handleHTTPError(resp *http.Response) error { + var errorDetail Error + decoder := json.NewDecoder(resp.Body) + err := decoder.Decode(&errorDetail) + if err != nil { + return err + } + + errorDetail.StatusCode = resp.StatusCode + return errorDetail +} diff --git a/acme/simple_http_challenge.go b/acme/simple_http_challenge.go index 4fc56646..fbcd9db0 100644 --- a/acme/simple_http_challenge.go +++ b/acme/simple_http_challenge.go @@ -48,6 +48,10 @@ func (s *simpleHTTPChallenge) Solve(chlng challenge, domain string) error { var challengeResponse challenge Loop: for { + if resp.StatusCode >= http.StatusBadRequest { + return handleHTTPError(resp) + } + err = json.NewDecoder(resp.Body).Decode(&challengeResponse) resp.Body.Close() if err != nil { @@ -61,10 +65,8 @@ Loop: case "pending": break case "invalid": - logger().Print("The server could not validate our request.") return errors.New("The server could not validate our request.") default: - logger().Print("The server returned an unexpected state.") return errors.New("The server returned an unexpected state.") }