src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java
--- a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java Fri Aug 30 13:11:16 2019 +0100
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java Fri Aug 30 15:42:27 2019 +0100
@@ -30,6 +30,8 @@
import java.net.Authenticator.RequestorType;
import java.util.Base64;
import java.util.HashMap;
+import java.util.concurrent.locks.ReentrantLock;
+
import sun.net.www.HeaderParser;
import sun.util.logging.PlatformLogger;
import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
@@ -58,6 +60,8 @@
// the cache can be used only once, so after the first use, it's cleaned.
static HashMap <String, Boolean> supported = null;
static ThreadLocal <HashMap <String, Negotiator>> cache = null;
+ private static final ReentrantLock negotiateLock = new ReentrantLock();
+
/* Whether cache is enabled for Negotiate/Kerberos */
private static final boolean cacheSPNEGO;
static {
@@ -126,40 +130,50 @@
*
* @return true if supported
*/
- private static synchronized boolean isSupportedImpl(HttpCallerInfo hci) {
- if (supported == null) {
- supported = new HashMap<>();
- }
- String hostname = hci.host;
- hostname = hostname.toLowerCase();
- if (supported.containsKey(hostname)) {
- return supported.get(hostname);
- }
+ private static boolean isSupportedImpl(HttpCallerInfo hci) {
+ negotiateLock.lock();
+ try {
+ if (supported == null) {
+ supported = new HashMap<>();
+ }
+ String hostname = hci.host;
+ hostname = hostname.toLowerCase();
+ if (supported.containsKey(hostname)) {
+ return supported.get(hostname);
+ }
- Negotiator neg = Negotiator.getNegotiator(hci);
- if (neg != null) {
- supported.put(hostname, true);
- // the only place cache.put is called. here we can make sure
- // the object is valid and the oneToken inside is not null
- if (cache == null) {
- cache = new ThreadLocal<>() {
- @Override
- protected HashMap<String, Negotiator> initialValue() {
- return new HashMap<>();
- }
- };
+ Negotiator neg = Negotiator.getNegotiator(hci);
+ if (neg != null) {
+ supported.put(hostname, true);
+ // the only place cache.put is called. here we can make sure
+ // the object is valid and the oneToken inside is not null
+ if (cache == null) {
+ cache = new ThreadLocal<>() {
+ @Override
+ protected HashMap<String, Negotiator> initialValue() {
+ return new HashMap<>();
+ }
+ };
+ }
+ cache.get().put(hostname, neg);
+ return true;
+ } else {
+ supported.put(hostname, false);
+ return false;
}
- cache.get().put(hostname, neg);
- return true;
- } else {
- supported.put(hostname, false);
- return false;
+ } finally {
+ negotiateLock.unlock();
}
}
- private static synchronized HashMap<String, Negotiator> getCache() {
- if (cache == null) return null;
- return cache.get();
+ private static HashMap<String, Negotiator> getCache() {
+ negotiateLock.lock();
+ try {
+ if (cache == null) return null;
+ return cache.get();
+ } finally {
+ negotiateLock.unlock();
+ }
}
@Override
@@ -197,7 +211,7 @@
* @return true if all goes well, false if no headers were set.
*/
@Override
- public synchronized boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) {
+ public boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) {
try {
String response;