aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2015-12-22 14:05:02 +0100
committerDimitri Sokolyuk <demon@dim13.org>2015-12-22 14:05:02 +0100
commit31bfb0ae8f6ff862425da04867a3712333e2ae52 (patch)
tree8a44e7374cce5f3b060b3f0b73e9e97fb2fc520a
parent366b6f8736986b663c040744daec2a908a843365 (diff)
Split things
-rw-r--r--client.go64
1 files 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