From 31bfb0ae8f6ff862425da04867a3712333e2ae52 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 22 Dec 2015 14:05:02 +0100 Subject: Split things --- client.go | 64 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/client.go b/client.go index 1b07095..50ed236 100644 --- a/client.go +++ b/client.go @@ -3,7 +3,6 @@ package acme import ( "encoding/json" "errors" - "fmt" "io/ioutil" "log" "net/http" @@ -18,23 +17,33 @@ type Links map[string]string // Client ... type Client struct { - Dir Directory + Directory + nonce chan string +} + +type nextStep struct { Link Links Location string - nonce chan string RetryAfter time.Duration } +func (c Client) replyNonce(r *http.Response) { + if rn := r.Header.Get("Replay-Nonce"); rn != "" { + log.Println(ansi.Color("NONCE", "blue"), rn) + c.nonce <- rn + } +} + // NewClient fetches directory and initializes nonce func NewClient(directory string) (*Client, error) { + c := &Client{nonce: make(chan string, 10)} resp, err := http.Get(directory) if err != nil { return nil, err } defer resp.Body.Close() - c := &Client{nonce: make(chan string, 10)} - c.parseHeader(resp) - err = json.NewDecoder(resp.Body).Decode(&c.Dir) + defer c.replyNonce(resp) + err = json.NewDecoder(resp.Body).Decode(&c.Directory) if err != nil { return nil, err } @@ -77,7 +86,7 @@ func (c *Client) post(uri string, s Signer, v interface{}) (*http.Response, erro if err != nil { return nil, err } - log.Println(ansi.Color("POST", "red+b"), string(body)) + log.Println(ansi.Color("POST", "red+b"), uri, string(body)) signed, err := s.Sign(body, c) if err != nil { @@ -89,9 +98,8 @@ func (c *Client) post(uri string, s Signer, v interface{}) (*http.Response, erro return nil, err } defer resp.Body.Close() - c.parseHeader(resp) + defer c.replyNonce(resp) log.Println(ansi.Color("STATUS", "yellow"), resp.Status) - log.Println(ansi.Color("HEADER", "green"), c) if resp.StatusCode >= http.StatusBadRequest { var p Problem @@ -117,29 +125,30 @@ func (c *Client) post(uri string, s Signer, v interface{}) (*http.Response, erro var linksRe = regexp.MustCompile(`^<(.*)>;rel="(.*)"`) -func (c *Client) parseHeader(r *http.Response) { - if rn := r.Header.Get("Replay-Nonce"); rn != "" { - c.nonce <- rn - } +func parseHeader(r *http.Response) nextStep { + var ns nextStep if lo := r.Header.Get("Location"); lo != "" { - c.Location = lo + ns.Location = lo } - c.Link = make(Links) + ns.Link = make(Links) for _, li := range r.Header["Link"] { re := linksRe.FindStringSubmatch(li) if len(re) == 3 { - c.Link[re[2]] = re[1] + ns.Link[re[2]] = re[1] } } if ra := r.Header.Get("Retry-After"); ra != "" { n, err := strconv.Atoi(ra) if err == nil { - c.RetryAfter = time.Second * time.Duration(n) + ns.RetryAfter = time.Second * time.Duration(n) } } + + log.Println(ansi.Color("NEXT", "cyan"), ns) + return ns } /* @@ -166,25 +175,29 @@ func (c *Client) Register(a *Account) error { Resource: ResNewReg, Contact: a.Contact, } - resp, err := c.post(c.Dir.NewReg, a, r) + resp, err := c.post(c.NewReg, a, r) + if err != nil && err.(Problem).Err != ErrMalformed { + return err + } + ns := parseHeader(resp) switch resp.StatusCode { case http.StatusConflict: // Query Location r = &Registration{Resource: ResRegister} - _, err = c.post(c.Location, a, r) + resp, err = c.post(ns.Location, a, r) if err != nil { return err } fallthrough case http.StatusCreated: // Agree to TOS - if tos := c.Link["terms-of-service"]; tos != "" { + if tos := ns.Link["terms-of-service"]; tos != "" { r = &Registration{ Resource: ResRegister, Contact: a.Contact, Agreement: tos, } - _, err = c.post(c.Location, a, r) + _, err = c.post(ns.Location, a, r) } } return err @@ -199,7 +212,10 @@ func (c *Client) Authorize(a *Account, domain []string) error { Resource: ResNewAuthz, Identifier: ident, } - resp, err := c.post(c.Dir.NewAuthz, a, r) + resp, err := c.post(c.NewAuthz, a, r) + if err != nil { + return err + } switch resp.StatusCode { case http.StatusCreated: for _, ch := range r.Challenges { @@ -216,10 +232,6 @@ func (c *Client) Authorize(a *Account, domain []string) error { return err } -func (c Client) String() string { - return fmt.Sprintf("Location: %v Links: %v", c.Location, c.Link) -} - //////////////////////////////////////////////////////////////////////// // Register -- cgit v1.2.3