WHOIS Abfragen a la .NET
Geschrieben von: Christoph Wille Des öfteren möchte man wissen, wem eine Domain gehört. Um an die Registrierungsinformationen zu kommen, geht man zur entsprechenden Registry (DENIC, Network Solutions, etc), und macht dort eine sogenannte WHOIS Abfrage (Lookup). Der Haken an der Sache ist halt der, daß man wissen muß, welche Registry für welche TLD's (Top Level Domain) zuständig ist. Auch wenn man alle TLD-zu-Registry Informationen hätte - die URL's zur Abfrageseite merkt man sich schon erst recht nicht auswendig. Weil eine gemeinsame gibt es ja nicht - noch nicht! Genau so eine Seite werden wir nämlich heute in diesem Artikel coden. Voraussetzung um den Sourcecode dieses Artikels verwenden zu können ist eine Installation des Microsoft .NET Framework SDK's auf einem Webserver. Weiters setze ich voraus, daß der Leser die Programmiersprache C# zu einem gewissen Grad beherrscht - es finden sich etliche Artikel auf diesem Server, um das notwendige Wissen zu erlernen. Eine Dot-Com Domain abfragenUm das Prinzip zu klären, wie eine WHOIS Abfrage funktioniert, nehmen wir uns als Beispiel die amerikanische Registry Network Solutions (siehe auch Screenshot): http://www.networksolutions.com/cgi-bin/whois/whois Alles, was man tun muß, ist den Domainnamen einzugeben, und auf Search zu klicken - und schon bekommt man die Registrierungsinformationen präsentiert. Was läuft aber im Hintergrund für eine Datenbank, die diese Anfragen ermöglicht? Die Datenbank ist die sogenannte WHOIS Datenbank, und sie hat eine hervorragende Eigenschaft: sie stellt über den TCP Port 43 eine Anfrageschnittstelle zur Verfügung! Und da das .NET Framework die TcpClient Klasse für uns zur Verfügung stellt, können wir uns die Daten somit direkt über diese Schnittstelle abholen - ohne Umwege über das Scrapen der Webseiten auf Network Solutions. Das folgende Beispiel ist die Minimalimplementierung eines Whois-Lookups. Es gibt nur minimale Fehlerbehandlung, und eine "Auswahl" der Domain ist im Moment noch nicht möglich (queryinternic.aspx): <% @Page Language="C#" %> <% @Import Namespace="System.Net.Sockets" %> <% @Import Namespace="System.Text" %> <% @Import Namespace="System.IO" %> <% TcpClient tcpc = new TcpClient(); try { tcpc.Connect("whois.networksolutions.com", 43); } catch(SocketException ex) { Response.Write(ex.ToString()); Response.End(); } String strDomain = "gotdotnet.com\r\n"; Byte[] arrDomain = Encoding.ASCII.GetBytes(strDomain.ToCharArray()); Stream s = tcpc.GetStream(); s.Write(arrDomain, 0, strDomain.Length); StreamReader sr = new StreamReader(tcpc.GetStream(), Encoding.ASCII); string strLine = null; while (null != (strLine = sr.ReadLine())) { Response.Write(strLine + "<br>"); } tcpc.Close(); %> Um mit der TcpClient Klasse arbeiten zu können, brauchen wir den System.Net.Sockets Namespace. Weiters verwenden wir alte Bekannte wie System.Text oder System.IO. Die meiste Arbeit in diesem Beispiel übernimmt die TcpClient Klasse: mit ihr kann ich zu einem Server über einen beliebigen Port verbinden (die Connect Methode erledigt das), und Daten hin und her schicken (über den Stream). Das Senden der Anfrage verlangt eine kleine Erläuterung: zum Schicken verwende ich den binären Stream ohne irgendwelche Wrapper. Daher muß ich den Anfragestring (mit CR+LF terminiert) in ein Bytearray umwandeln (mit ASCII Encoding), und kann dann die gewünschte Anzahl von Bytes an den entfernten Server schicken. Das Abholen der Daten passiert dann über den StreamReader, der ein bequemes und direktes Arbeiten mit Zeichendaten erlaubt. Und da das Beispiel auch bis zum Schluß einfach bleibt, werden die gelesenen Daten sofort an den Client weitergeschickt - das Resultat zeigt der folgende Screenshot. Verschiedene Registries abfragenJetzt wissen wir, wie wir den WHOIS Server von Network Solutions abfragen. Haben wir damit etwas erreicht? Aber sicher - (fast) jede Registry hat einen solchen, und das Procedere ist immer das Gleiche. Man braucht nur ein Liste der Registries und ihrer WHOIS Server. Genau das habe ich im nun folgenden Beispiel implementiert: es hat ein kleines Formular, in dem man den Domainnamen eingeben kann. ASP.NET am Server checkt ob der Domainname gültig ist, und entscheidet dann anhand des Domainsuffixes (.com, .de, etc) welcher WHOIS Server welcher Registry um Informationen zu dieser Domain gefragt werden soll. Der Code ist bereits über 100 Zeilen lang, deshalb habe ich die Erklärung aufgesplittet. Wer den Überblick behalten will, sollte sich den gesamten Code der Datei queryregistries.aspx in einem zweiten Fenster öffnen. Das FormularZum verwendeten Formular gibt es eigentlich nichts besonderes zu sagen. Es hat ein Eingabefeld, einen Button, und eine Label Control, in der dann das Resultat ausgegeben wird. <html> <head> <title></title> </head> <body> <form runat="server"> Domain name: <asp:TextBox id="txtDomain" value="aspheute.com" runat="server" /> <asp:Button id="btnQuery" OnClick="doQuery" text="Query!" runat="server" /> <BR><HR width="100%"><BR> <asp:label id="txtResult" runat="server" /> </form> </body> </html> Das Button-Event doQueryIn diesem Event ist der meiste neue Code beheimatet. Grundsätzlich macht er folgendes:
Nun aber zum Sourcecode: void doQuery(Object sender, EventArgs e) { String strDomain = txtDomain.Text; char[] chSplit = {'.'}; string[] arrDomain = strDomain.Split(chSplit); // es darf genau ein domain name + ein suffix sein if (arrDomain.Length != 2) { return; } // das suffic darf nur 2 oder 3 zeichen lang sein int nLength = arrDomain[1].Length; if (nLength != 2 && nLength != 3) { return; } Hashtable table = new Hashtable(); table.Add("de", "whois.denic.de"); table.Add("be", "whois.dns.be"); table.Add("gov", "whois.nic.gov"); table.Add("mil", "whois.nic.mil"); String strServer = "whois.networksolutions.com"; if (table.ContainsKey(arrDomain[1])) { strServer = table[arrDomain[1]].ToString(); } else if (nLength == 2) { // 2-letter TLD's always default to RIPE in Europe strServer = "whois.ripe.net"; } String strResponse; bool bSuccess = DoWhoisLookup(strDomain, strServer, out strResponse); if (bSuccess) { txtResult.Text = strResponse; } else { txtResult.Text = "Lookup failed"; } } Der oberste Block kümmert sich nur darum festzustellen, ob die Eingabe gültig ist (die Fehlermeldungen sollten Sie vielleicht doch noch ausgeben). Danach baue ich einen Hashtable auf, der mir die TLD's zu den jeweiligen WHOIS Servern verlinkt. Ich habe mir nur die wichtigsten TLD's herausgepickt, allerdings reicht das, um alle US und europäischen Domains abfragen. Nach dem Anlegen des Hashtable entscheidet der Code, welcher Server zu verwenden ist. Standardmäßig ist es der von Network Solutions, ansonsten entweder ein spezieller, oder für 2-Buchstaben TLD's der RIPE Server. Auf alle Fälle muß man den Hashtable erweitern, falls man auch den asiatischen Raum oder Südamerika abfragen möchte. Da wir nun wissen, nach was wir fragen sollen, und vor allem wo, können wir nun die Arbeit der Funktion DoWhoisLookup überlassen - und dann einfach das Ergebnis ausgeben. Das Abfragen - DoWhoisLookupJetzt sind wir beim Arbeitstier der Anwendung. Diese Funktion führt die Abfrage durch, und die gute Nachricht ist, daß wir wirklich den gesamten Sourcecode von der Network Solutions Abfrage verwenden konnten - ich habe nur etwas Exception Handling eingebaut, damit diese Applikation auch wirklich robust ist. bool DoWhoisLookup(String strDomain, String strServer, out String strResponse) { strResponse = "none"; bool bSuccess = false; TcpClient tcpc = new TcpClient(); try { tcpc.Connect(strServer, 43); } catch(SocketException ex) { strResponse = "Could not connect to Whois server"; return false; } strDomain += "\r\n"; Byte[] arrDomain = Encoding.ASCII.GetBytes(strDomain.ToCharArray()); try { Stream s = tcpc.GetStream(); s.Write(arrDomain, 0, strDomain.Length); StreamReader sr = new StreamReader(tcpc.GetStream(), Encoding.ASCII); StringBuilder strBuilder = new StringBuilder(); string strLine = null; while (null != (strLine = sr.ReadLine())) { strBuilder.Append(strLine+"<br>"); } tcpc.Close(); bSuccess = true; strResponse = strBuilder.ToString(); } catch(Exception e) { strResponse = e.ToString(); } return bSuccess; } Wie bereits angekündigt, es ist das Exception Handling dazugekommen. Weiters verwende ich jetzt die StringBuilder Klasse, da ich ja den Response des WHOIS Servers an den Aufrufer und nicht direkt an Client zurückgeben muß. Und das war dann auch schon der gesamte Magic! SchlußbemerkungDank der .NET Framework Klassen waren wir in kürzester Zeit in der Lage, uns ein komfortables Cross-Registry WHOIS Anfrageformular zu basteln. Der einzige Schönheitsfehler ist leicht auszubessern: der Hashtable muß noch um die restlichen internationalen WHOIS Server erweitert werden, aber zumindest die vom Standpunkt eines Europäers wichtigsten Registries können schon abgefragt werden! Download des CodesKlicken Sie hier, um den Download zu starten. Verwandte Artikel
.NET Komponenten in COM+ Clients einsetzen Links zu anderen SitesWenn Sie jetzt Fragen haben...Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten. Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist. Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.
Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.
©2000-2006 AspHeute.com |