Do not get stuck when server accidentally starts responding with bad data (#349)

If `links["next"] == ""` the early return does not send neither success, nor failure to outer code,
which leads to whole `getChallenges` method being stuck forever, cause it waits for either `resc` or `errc` to receive message.
This commit is contained in:
Pavel Forkert 2017-02-19 06:17:22 +02:00 committed by xenolf
parent 9f94aabbd2
commit 661e5e690c
2 changed files with 38 additions and 0 deletions

View file

@ -535,6 +535,7 @@ func (c *Client) getChallenges(domains []string) ([]authorizationResource, map[s
links := parseLinks(hdr["Link"]) links := parseLinks(hdr["Link"])
if links["next"] == "" { if links["next"] == "" {
logf("[ERROR][%s] acme: Server did not provide next link to proceed", domain) logf("[ERROR][%s] acme: Server did not provide next link to proceed", domain)
errc <- domainError{Domain: domain, Error: errors.New("Server did not provide next link to proceed")}
return return
} }

View file

@ -202,6 +202,43 @@ func TestValidate(t *testing.T) {
} }
} }
func TestGetChallenges(t *testing.T) {
var ts *httptest.Server
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET", "HEAD":
w.Header().Add("Replay-Nonce", "12345")
w.Header().Add("Retry-After", "0")
writeJSONResponse(w, directory{NewAuthzURL: ts.URL, NewCertURL: ts.URL, NewRegURL: ts.URL, RevokeCertURL: ts.URL})
case "POST":
writeJSONResponse(w, authorization{})
}
}))
defer ts.Close()
keyBits := 512 // small value keeps test fast
keyType := RSA2048
key, err := rsa.GenerateKey(rand.Reader, keyBits)
if err != nil {
t.Fatal("Could not generate test key:", err)
}
user := mockUser{
email: "test@test.com",
regres: &RegistrationResource{NewAuthzURL: ts.URL},
privatekey: key,
}
client, err := NewClient(ts.URL, user, keyType)
if err != nil {
t.Fatalf("Could not create client: %v", err)
}
_, failures := client.getChallenges([]string{"example.com"})
if failures["example.com"] == nil {
t.Fatal("Expecting \"Server did not provide next link to proceed\" error, got nil")
}
}
// writeJSONResponse marshals the body as JSON and writes it to the response. // writeJSONResponse marshals the body as JSON and writes it to the response.
func writeJSONResponse(w http.ResponseWriter, body interface{}) { func writeJSONResponse(w http.ResponseWriter, body interface{}) {
bs, err := json.Marshal(body) bs, err := json.Marshal(body)