Expire resource directory cache.

A long term AcmeClient instance could miss changes to the directory,
so the cache is invalidated after 1 hour.
pull/17/merge
Richard Körber 2016-01-09 17:23:05 +01:00
parent 06ccd6f2e1
commit c83df44eed
2 changed files with 22 additions and 2 deletions

View File

@ -15,6 +15,7 @@ package org.shredzone.acme4j.impl;
import java.net.HttpURLConnection;
import java.net.URI;
import java.util.Date;
import java.util.EnumMap;
import java.util.Map;
@ -38,6 +39,7 @@ public class GenericAcmeClient extends AbstractAcmeClient {
private final AcmeClientProvider provider;
private final URI directoryUri;
private final Map<Resource, URI> directoryMap = new EnumMap<>(Resource.class);
/* package protected */ Date directoryCacheExpiry;
/**
* Creates a new {@link GenericAcmeClient}.
@ -86,7 +88,9 @@ public class GenericAcmeClient extends AbstractAcmeClient {
throw new NullPointerException("resource must not be null");
}
if (directoryMap.isEmpty()) {
Date now = new Date();
if (directoryMap.isEmpty() || !directoryCacheExpiry.after(now)) {
if (directoryUri == null) {
throw new IllegalStateException("directoryUri was null on construction time");
}
@ -100,7 +104,12 @@ public class GenericAcmeClient extends AbstractAcmeClient {
// use nonce header if there is one, saves a HEAD request...
conn.updateSession(getSession());
directoryMap.putAll(conn.readDirectory());
Map<Resource, URI> newMap = conn.readDirectory();
// only reached when readDirectory did not throw an exception
directoryMap.clear();
directoryMap.putAll(newMap);
directoryCacheExpiry = new Date(now.getTime() + 60 * 60 * 1000L);
}
}
return directoryMap.get(resource);

View File

@ -19,6 +19,7 @@ import static org.mockito.Mockito.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@ -107,6 +108,16 @@ public class GenericAcmeClientTest {
verify(mockConnection, times(1)).readDirectory();
verify(mockProvider).createConnection();
// Simulate a cache expiry
client.directoryCacheExpiry = new Date();
// Make sure directory is read once again
assertThat(client.resourceUri(Resource.NEW_AUTHZ), is(new URI("http://example.com/acme/new-authz")));
assertThat(client.resourceUri(Resource.NEW_CERT), is(new URI("http://example.com/acme/new-cert")));
assertThat(client.resourceUri(Resource.NEW_REG), is(nullValue()));
verify(mockConnection, times(2)).sendRequest(directoryUri);
verify(mockConnection, times(2)).readDirectory();
}
}