.HU domain ellenőrzés host névből

Szükségem volt arra, hogy egy adott string-ről eldöntsem, érvényes magyar (.hu) domain név-e avagy sem. Utánajártam a témának, és kiderítettem, hogy melyek a pontos szabályok .hu domain regisztrációja esetében:

  • A domain név csak angol kisbetűket (a-z), számokat (0-9), kötőjelet (-) és magyar ékezetes kisebetűket (áéíóöőúüű) tartalmazhat.
  • Az ékezetes domain neveknek létezik, egy un. IDN formával alakja, amely kódolt formában tartalmaz az ékezetes karaktereket. Ezek a domain nevek xn-- karakterekkel kezdődnek.
  • Nem lehet rövidebb 2 karakternél, és nem lehet hosszabb 40 karakternél. (Nincs infó, hogy az ékezetes karakterekkel kell-e számolni, vagy az eltérő hosszúságú IDN.)
  • Másodszintű közdomaineket (pl. info.hu) nem lehet regisztrálni, de eléjük egy harmadszintű nevet lehet regisztrálni (pl. edgarpe.info.hu érvényes lenne.)
  • Vannak védett nevek (pl. www) amelyeket nem lehet regisztrálni sem másod, sem harmad szinten. A net és az internet, bár védett neveke, a net.hu és az internet.hu domainek mégis lézetnek.
  • Vannak zárolt domain nevek (pl. turizmus.hu), amelyeket nem lehet regisztrálni.
  • Jelenleg (2012. március 12.) 31 darab másodszintű közdomain van, 28 darab védett név, és 28 darab zárolt név.

Több időt töltöttem el a szabályok kinyomozásával és a php nyelvű teszt függvény megírásával, mint amennyit szerettem volna.

Megosztom itt is, ha valakinek spórolok vele pár órát, már megérte.

Végül kicsit többet oldottam meg, mint egy ellenőrző: a függvény bemenete egy hostnév, visszatérési értéke a hostból kinyert domain név, vagy FALSE, ha nem érvényes a név. Utóbbi esetben a referencia szerínt átadott második $error paraméterben meg is mondja, mi volt a gond. Tehát pl. a valami.edgarpe.hu bemenetre, a válasz edgarpe.hu lesz, a valami.info.edgarpe.hu bemenetre pedig edgarpe.info.hu lesz a válasz.

Kizárólag .HU TLD domain nevekre működik.

Végül egy tipp: ha nem host név áll rendelkezésre, hanem teljes URL akkor érdemes lehet használni a parse_url php-s függvény átírását is, ritkábban hasal el rossz bemenetekre.

Itt a kód, de letölthető formmában is megvan az oldal alján:

<?php
/**
 * .HU domain név ellenörző. Ellenörzi, hogy egy adott host érvényes magyar .hu
 * domain-hez tartozik-e.
 *
 * Figyelembe vett szabályok:
 * - a domain név hossza (min 2, max 40 karakter)
 * - érvényes karakterek (a-z, 0-9, -, áéíóöőúüű)
 * - kötőjel szabályok a név elején, közepén és végén
 * - másodszintű közdomainek
 * - védett nevek
 * - zárolt nevek
 *
 * @param $host
 *   Host név, amely feltételezhetően egy érvényes .hu domain névhez tartozik.
 * @param $error
 *   Referencia szerint átadva. Hibaüzenet, ha a host nem .hu domain része.
 * @return
 *   A domain név (string) amihez a $host tartozik, vagy FALSE ha téves.
 */
function domain_from_host($host, &$error = NULL) {
 
$level2 = array(
   
'co', 'info', 'org', 'priv', 'sport', 'tm', '2000', 'agrar',
   
'bolt', 'casino', 'city', 'erotica', 'erotika', 'film', 'forum', 'games',
   
'hotel', 'ingatlan', 'jogasz', 'konyvelo', 'lakas', 'media', 'news',
   
'reklam', 'sex', 'shop', 'suli', 'szex', 'tozsde', 'utazas', 'video',
  );
 
 
$protected = array(
   
'ac', 'arpa', 'biz', 'co', 'com', 'dns', 'email', 'e-mail', 'firm', 'ftp',
   
'gov', 'ind', 'info', 'internet', 'iskola', 'mail', 'mx', 'net', 'nom',
   
'ns', 'nui', 'org', 'pp', 'priv', 'sport', 'tm', 'web', 'www',
  );

 
$closed = array(
   
'accomodation.hu', 'aruhaz.hu', 'aukcio.hu', 'auto.hu', 'befektetes.hu',
   
'bor.hu', 'broker.hu', 'business.hu', 'butor.hu', 'cash.hu', 'credit.hu',
   
'house.hu', 'jacht.hu', 'kamat.hu', 'konyv.hu', 'magazin.hu', 'oras.hu',
   
'orszag.hu', 'pc.hu', 'search.hu', 'szabadido.hu', 'telek.hu', 'trade.hu',
   
'translation.hu', 'travel.hu', 'turizmus.hu', 'voip.hu', 'vpn.hu',
  );
 
 
$error = NULL;

  if (
preg_match('/^[a-z0-9\\á\é\í\ó\ö\ő\ú\ü\ű\-\.]+$/', $host) !== 1) {
   
$error = 'Invalid characters';
    return
FALSE;
  }
 
 
$parts = array_reverse(explode('.', $host));
 
  if (
count($parts) < 2) {
   
$error = 'Invalid format.';
    return
FALSE;
  }
 
  if (
$parts[0] !== 'hu') {
   
$error = 'Not .hu domain.';
    return
FALSE;
  }
 
  if (
in_array($parts[1] .'.'. $parts[0], $closed)) {
   
$error = 'Closed domain.';
    return
FALSE;
  }
 
  if (
in_array($parts[1], $level2)) {
    if (isset(
$parts[2])) {
     
$name = $parts[2];
     
$suffix = '.'. $parts[1] .'.hu';
    }
    else {
     
$error = 'Second level domain.';
      return
FALSE;
    }
  }
  else {
   
$name = $parts[1];
   
$suffix = '.hu';
  }
 
  if (
in_array($name, $protected) && !in_array($name . $suffix, array('internet.hu', 'net.hu'))) {
   
$error = 'Protected name.';
    return
FALSE;
  }
 
  if (
mb_strlen($name) < 2) {
   
$error = 'Domain too short.';
    return
FALSE;
  }

  if (
mb_strlen($name) > 40) {
   
$error = 'Domain too long.';
    return
FALSE;
  }
 
  if (
$name[0] == '-') {
   
$error = 'Name stats with \'-\' character.';
    return
FALSE;
  }
 
  if (
$name[strlen($name) - 1] == '-') {
   
$error = 'Name ends with \'-\' character.';
    return
FALSE;
  }
 
 
$before_needle = strstr($name, '--', TRUE);
  if (
$before_needle === 'xn') {
   
$before_needle = strstr(substr($name, 4), '--');
  }
  if (
$before_needle !== FALSE) {
   
$error = 'Double minus (\'--\') character found.';
    return
FALSE;
  }
 
  return
$name . $suffix;
}
?>

Ha hibákért és a használatból eredő károkért nem vállalok felelősséget. Viszont ha megírjátok a hibát kommentben, akkor javítani, ha tudom.