Java: URL#equals() ist gefährlich

java.net.URL implementiert equals(Object). Also was liegt näher, als URLs damit zu vergleichen? Gefährlich.
  public static void main(String[] args) throws Exception
  {
    URL u1 = new URL("http://www.willuhn.de");
    URL u2 = new URL("http://www.jameica.org");
    
    System.out.println(u1.equals(u2));
  }
Ausgabe:
true
Die beiden URLs verweisen zwar per DNS auf die selbe IP. Per VirtualHost-Konfiguration werden jedoch unterschiedliche Webseiten angezeigt. Weder ist die URL identisch, noch der Inhalt der Webseite. Dennoch liefert der Vergleich "true". Wegen gleichem Protokoll, Port und Pfad sowie gleicher IP. Im Javadoc findet sich hierzu auch:
Two URL objects are equal if they have the same protocol, reference equivalent hosts, have the same port number on the host, and the same file and fragment of the file.
Two hosts are considered equivalent if both host names can be resolved into the same IP addresses [...]
Note: The defined behavior for equals is known to be inconsistent with virtual hosting in HTTP.
Im letzten Satz findet sich auch ein entsprechender Hinweis, den man schnell überlesen kann.

Hinzu kommt noch, dass java.net.URLStreamHandler (übernimmt den eigentlichen Vergleich in der "equals"-Methode) für das DNS-Resolve InetAddress.getByName(host) verwendet. Welches so implementiert ist:
return InetAddress.getAllByName(host)[0];
Da wird also pauschal die erste gefundene IP-Adresse zu dem Host geliefert. Hat man nun aber eine Lastverteilung per DNS Round Robin für die Domain eingerichtet, dann ist der Rückgabewert von "equals" noch nicht mal deterministisch. Je nachdem, welche IP gerade zufällig zurückkommt, liefert der Vergleich manchmal true und manchmal false.

Beim Vergleich typischer HTTP-URLs von Webseiten ist es daher meiner Meinung nach sicherer, einfach einen String-Vergleich zu machen. Das ist zwar auch nicht 100%-ig sicher, dafür aber aber pragmatischer, schneller (weil kein DNS-Lookup nötig ist) und nicht so tückisch.

Trackbacks

Trackback-URL für diesen Eintrag

Dieser Link ist nicht aktiv. Er enthält die Trackback-URI zu diesem Eintrag. Sie können diese URI benutzen, um Ping- und Trackbacks von Ihrem eigenen Blog zu diesem Eintrag zu schicken. Um den Link zu kopieren, klicken Sie ihn mit der rechten Maustaste an und wählen "Verknüpfung kopieren" im Internet Explorer oder "Linkadresse kopieren" in Mozilla/Firefox.

Keine Trackbacks

Kommentare

Ansicht der Kommentare: Linear | Verschachtelt

ThomasS am :

Interessant. Danke.

Die Kommentarfunktion wurde vom Besitzer dieses Blogs in diesem Eintrag deaktiviert.