forked from ericchiang/go-acme
/
error.go
50 lines (44 loc) · 1.21 KB
/
error.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package letsencrypt
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
// https://tools.ietf.org/html/draft-ietf-appsawg-http-problem-01
// A HTTP error generated by the ACME server.
type Error struct {
Typ string `json:"type"`
Status int `json:"status"`
Detail string `json:"detail"`
}
func (err *Error) Error() string {
return fmt.Sprintf("acme error '%s': %s", err.Typ, err.Detail)
}
func checkHTTPError(resp *http.Response, expCode int) error {
if resp.StatusCode == expCode {
return nil
}
// errors are only defined for status codes 4XX and 5XXX
// https://letsencrypt.github.io/acme-spec/#errors
if !(resp.StatusCode >= 400 && resp.StatusCode < 600) {
return fmt.Errorf("acme: expected Status %d %s, got %s", expCode, http.StatusText(expCode), resp.Status)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("read body: %v", err)
}
var errData struct {
Typ string `json:"type"`
Detail string `json:"detail"`
}
if err := json.Unmarshal(body, &errData); err != nil {
return fmt.Errorf("parsing error: %v", err)
}
return &Error{
Typ: strings.TrimPrefix(errData.Typ, "urn:acme:error:"),
Detail: errData.Detail,
Status: resp.StatusCode,
}
}