I've come across some code that's using
Protocol.registerProtocol
in an attempt to block some TLS ciphers for a request, and retry the request with it re-enabled at times, depending on other factors.
But is Protocol.registerProtocol
causing a global change - ie will other threads be affected by this?
Here's the code in question:
protected static HostConfiguration buildTLSConfig(String uri, HostConfiguration config,
boolean blockTLS1)
throws MalformedURLException
{
scheme = "https";
if (baseHttps == null)
{
baseHttps = Protocol.getProtocol(scheme);
baseFactory = baseHttps.getSocketFactory();
}
URL newUrl = new URL(uri);
defaultPort = baseHttps.getDefaultPort();
if (blockTLS1)
{
ProtocolSocketFactory customFactory =
new CustomHttpsSocketFactory(baseFactory, TLS_PREFERRED_PROTOCOLS);
Protocol applyHttps = new Protocol(scheme, customFactory, defaultPort);
Protocol.registerProtocol(scheme, applyHttps);
config.setHost(newUrl.getHost(), defaultPort, applyHttps);
}
else
{
Protocol.registerProtocol(scheme, baseHttps);
config.setHost(newUrl.getHost(), defaultPort, baseHttps);
}
return config;
}
Yes, all threads will be affected by the change.
If we look at org.apache.commons.httpclient.protocol.Protocol
, we see a global protocol Map
:
/** The available protocols */
private static final Map PROTOCOLS = Collections.synchronizedMap(new HashMap());
And registerProtocol()
simply modifying it:
public static void registerProtocol(String id, Protocol protocol) {
// . . .
PROTOCOLS.put(id, protocol);
}
At least it's synchronized, so there won't be a race during modification.