mirror of https://github.com/shred/acme4j
Fix potential race condition when threads share a session
parent
08eaa61f75
commit
1f6d8aea0b
|
@ -22,6 +22,7 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import org.shredzone.acme4j.challenge.Challenge;
|
import org.shredzone.acme4j.challenge.Challenge;
|
||||||
|
@ -39,14 +40,14 @@ import org.shredzone.acme4j.util.JSON;
|
||||||
* volatile data.
|
* volatile data.
|
||||||
*/
|
*/
|
||||||
public class Session {
|
public class Session {
|
||||||
private final Map<Resource, URI> resourceMap = new EnumMap<>(Resource.class);
|
private final AtomicReference<Map<Resource, URI>> resourceMap = new AtomicReference<>();
|
||||||
|
private final AtomicReference<Metadata> metadata = new AtomicReference<>();
|
||||||
private final URI serverUri;
|
private final URI serverUri;
|
||||||
private final AcmeProvider provider;
|
private final AcmeProvider provider;
|
||||||
|
|
||||||
private KeyPair keyPair;
|
private KeyPair keyPair;
|
||||||
private byte[] nonce;
|
private byte[] nonce;
|
||||||
private JSON directoryJson;
|
private JSON directoryJson;
|
||||||
private Metadata metadata;
|
|
||||||
private Locale locale = Locale.getDefault();
|
private Locale locale = Locale.getDefault();
|
||||||
protected Instant directoryCacheExpiry;
|
protected Instant directoryCacheExpiry;
|
||||||
|
|
||||||
|
@ -183,7 +184,7 @@ public class Session {
|
||||||
*/
|
*/
|
||||||
public URI resourceUri(Resource resource) throws AcmeException {
|
public URI resourceUri(Resource resource) throws AcmeException {
|
||||||
readDirectory();
|
readDirectory();
|
||||||
return resourceMap.get(Objects.requireNonNull(resource, "resource"));
|
return resourceMap.get().get(Objects.requireNonNull(resource, "resource"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,7 +195,7 @@ public class Session {
|
||||||
*/
|
*/
|
||||||
public Metadata getMetadata() throws AcmeException {
|
public Metadata getMetadata() throws AcmeException {
|
||||||
readDirectory();
|
readDirectory();
|
||||||
return metadata;
|
return metadata.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -204,26 +205,28 @@ public class Session {
|
||||||
private void readDirectory() throws AcmeException {
|
private void readDirectory() throws AcmeException {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Instant now = Instant.now();
|
Instant now = Instant.now();
|
||||||
if (directoryJson == null || !directoryCacheExpiry.isAfter(now)) {
|
if (directoryJson != null && directoryCacheExpiry.isAfter(now)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
directoryJson = provider().directory(this, getServerUri());
|
directoryJson = provider().directory(this, getServerUri());
|
||||||
directoryCacheExpiry = now.plus(Duration.ofHours(1));
|
directoryCacheExpiry = now.plus(Duration.ofHours(1));
|
||||||
|
}
|
||||||
|
|
||||||
JSON meta = directoryJson.get("meta").asObject();
|
JSON meta = directoryJson.get("meta").asObject();
|
||||||
if (meta != null) {
|
if (meta != null) {
|
||||||
metadata = new Metadata(meta);
|
metadata.set(new Metadata(meta));
|
||||||
} else {
|
} else {
|
||||||
metadata = new Metadata(JSON.empty());
|
metadata.set(new Metadata(JSON.empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceMap.clear();
|
Map<Resource, URI> map = new EnumMap<>(Resource.class);
|
||||||
for (Resource res : Resource.values()) {
|
for (Resource res : Resource.values()) {
|
||||||
URI uri = directoryJson.get(res.path()).asURI();
|
URI uri = directoryJson.get(res.path()).asURI();
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
resourceMap.put(res, uri);
|
map.put(res, uri);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
resourceMap.set(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue