I am implementing a hostname verifier for my SSL client. I know that the Default Hostname Verifier of the HTTPS URL connection is static. My problem is that I do not want the hostname verification to be static because I have multiple threads in my client accessing this hostname verifier at the same time.
At the moment my code looks like this,:
I have an inner class for the hostname verification,
public class CreateHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
try {
if (mInstance.getHost().equals(InetAddress.getByName(hostname)))
return true;
else if (hostname.equals(mInstance.getHost().getHostAddress()))
return true;
else if (hostname.equals(mInstance.getHost().getCanonicalHostName()))
return true;
else
return false;
} catch (UnknownHostException e) {
System.out.println("Unknown Host");
}
return false;
}
}
}
I call this class when I am building my endpoint,
address = mInstance.getSecureConnectionEndpoint();
try {
HttpsURLConnection Connection = (HttpsURLConnection) address.openConnection();
CreateHostnameVerifier hv = new CreateHostnameVerifier();
Connection.setDefaultHostnameVerifier(hv);
} catch (IOException e1) {
e1.printStackTrace();
}
Because I use setDefaultHostnameVerifer
and try to access it in a non static way by doing Connection.setDefaultHostnameVerifier
I get warnings like:
The static method setDefaultHostnameVerifier(HostnameVerifier) from the type HttpsURLConnection should be accessed in a static way
But this works absolutely fine, but in case I try to access it in a non-static way:
Connection.setHostnameVerifier(hv);
It does not work.
Can someone explain me the difference between the two, i.e., setHostnameVerifer
and setDefaultHostnameVerifier
.
My problem is that I do not want the hostname verification to be static because I have multiple threads in my client accessing this hostname verifier at the same time.
This "requirement" is based on a misapprehension.
There is nothing per se wrong with multiple threads using the same HostnameVerifier
. Unless you do something very strange, one of these objects should have no mutable state. Provided that your shared object HostnameVerifier
instance is safely published (and immutable), it can be safely used by multiple threads without any need for synchronization.
Can someone explain me the difference between the two, i.e.,
setHostnameVerifier
andsetDefaultHostnameVerifier
.
The javadoc for HttpsURLConnection.setHostnameVerifier
explains it:
public void setHostnameVerifier(HostnameVerifier v)
Sets the
HostnameVerifier
for this instance. New instances of this class inherit the default static hostname verifier set bysetDefaultHostnameVerifier
. Calls to this method replace this object'sHostnameVerifier
.
One possible reason that setHostnameVerifier
is not working for you may be that you are calling it too late; i.e. after the connection has been established, and the verification has been performed.
The way to avoid the warning is to set the default verifier like this:
HttpsURLConnection.setDefaultHostnameVerifier(hv);
It is a static method, so it should be called via the class name not via an instance reference. (That's what the warning is telling you ...)