pax_global_header00006660000000000000000000000064127055430400014512gustar00rootroot0000000000000052 comment=debcc4e8364dd699b985ca09a58cc1a4493c67be php-net-publicsuffix-0.2/000077500000000000000000000000001270554304000154275ustar00rootroot00000000000000php-net-publicsuffix-0.2/Net/000077500000000000000000000000001270554304000161555ustar00rootroot00000000000000php-net-publicsuffix-0.2/Net/PublicSuffix.php000066400000000000000000000114631270554304000212760ustar00rootroot00000000000000 * @copyright 2012 the author * @license GPL-3+ * @version 0.1 */ class Net_PublicSuffix_Match { var $rule; var $match; function __construct($rule, $match) { $this->rule = $rule; $this->match = $match; } function is_exception() { return $this->rule[0] == '!'; } }; class Net_PublicSuffix { static $singleton = null; var $table; function __construct($fname='/usr/share/publicsuffix/public_suffix_list.dat') { $this->table = array(); $this->table['*'] = array('.' => '*'); $this->import_names($fname); } static function _init_singleton() { if (is_null(Net_PublicSuffix::$singleton)) Net_PublicSuffix::$singleton = new Net_PublicSuffix(); } static function registered_domain($name) { Net_PublicSuffix::_init_singleton(); return Net_PublicSuffix::$singleton->get_registered_domain($name); } static function prevailing_suffix_rule($name) { Net_PublicSuffix::_init_singleton(); return Net_PublicSuffix::$singleton->get_prevailing_public_suffix_rule($name); } // FIXME: this is horrifically slow -- takes > 1sec to read the // canonical public suffix list (as of 2012-08-13) on a 900Mhz Celeron :( function import_names($fname) { $handle = @fopen($fname, "r"); if ($handle) { while (($buffer = fgets($handle, 4096)) !== false) { $buffer = preg_replace('/[[:space:]].*$/', '', $buffer); if (strlen($buffer) == 0 || $buffer[0] == '/') { // skip blank or comment lines. } else { $exception = ($buffer[0] == '!'); if ($exception) $buffer = substr($buffer,1); $buffer = Net_PublicSuffix::_canonicalize($buffer); $labels = array_reverse(explode('.', $buffer)); $x =& $this->table; foreach ($labels as $label) { if (!array_key_exists($label, $x)) { $x[$label] = array(); } $x =& $x[$label]; } $x['.'] = ($exception ? '!' : '').$buffer; // we store the full rule in this position } } if (!feof($handle)) { echo "Error: unexpected fgets() fail\n"; } fclose($handle); } } static function _canonicalize($name) { return mb_strtolower(idn_to_ascii($name)); } static function _get_public_suffix_rules($name, &$tree, $matched) { $ret = array(); if (array_key_exists('.', $tree)) { $ret[] = new Net_PublicSuffix_Match($tree['.'], $matched); } if (count($name) == 0) return $ret; $matched[] = $name[0]; if (array_key_exists('*', $tree)) { $ret = array_merge($ret, Net_PublicSuffix::_get_public_suffix_rules(array_slice($name, 1), $tree['*'], $matched)); } if (array_key_exists($name[0], $tree)) { $ret = array_merge($ret, Net_PublicSuffix::_get_public_suffix_rules(array_slice($name, 1), $tree[$name[0]], $matched)); } return $ret; } function get_matching_public_suffix_rules($name) { $name = Net_PublicSuffix::_canonicalize($name); $labels = array_reverse(explode('.', trim($name))); // if any label element is zero-length, we should return NULL for the whole string. if (count(array_filter($labels, function($x) { return empty($x); }))) return array(); return Net_PublicSuffix::_get_public_suffix_rules($labels, $this->table, array()); } function get_prevailing_public_suffix_rule($name) { $name = Net_PublicSuffix::_canonicalize($name); $rules = $this->get_matching_public_suffix_rules($name); $myrule = null; $maxlen = 0; foreach ($rules as $rule) { // what if there are more than one exception rule? // at the moment, we just choose the first one. if ($rule->is_exception()) { $myrule =& $rule; break; } if (count($rule->match) > $maxlen) { $maxlen = $rule->match; $myrule =& $rule; } } return $myrule; } function get_registered_domain($name) { $is_ascii = mb_check_encoding($name, 'ASCII'); $name = Net_PublicSuffix::_canonicalize($name); $rule = $this->get_prevailing_public_suffix_rule($name); if (is_null($rule)) return null; if ($rule->is_exception()) { $ret = join('.', array_reverse($rule->match)); } else { $labels = explode('.', trim($name)); if (count($labels) <= count($rule->match)) return null; $ret = join('.', array_slice($labels, -1 * count($rule->match) - 1)); } if (!$is_ascii) return idn_to_utf8($ret); return $ret; } } /* * Local Variables: * indent-tabs-mode: nil * c-basic-offset: 2 * End: */ php-net-publicsuffix-0.2/README000066400000000000000000000020271270554304000163100ustar00rootroot00000000000000Net_PublicSuffix README ======================= Net_PublicSuffix is a php class designed to facilitate access to the public suffix list (see http://publicsuffix.org/). Its primary interface is Net_PublicSuffix::registered_domain($d), which determines the publicly registerable part of DNS label $d. For example: ------------------- require_once('Net/PublicSuffix.php'); $a = Net_PublicSuffix::registered_domain("www.example.com"); $b = Net_PublicSuffix::registered_domain("www.monkeys.example.co.uk"); // $a should be "example.com" // $b should be "example.co.uk" ------------------- Note that the module depends heavily on the existence of a local copy of the public suffix list, which it assumes to be in the filesystem at: /usr/share/publicsuffix/public_suffix_list.dat On debian systems, you should be able to get this by installing the "publicsuffix" package. I haven't yet bothered to get this module into PEAR properly. If anyone wants to help do that, please let me know. -- Daniel Kahn Gillmor php-net-publicsuffix-0.2/TODO000066400000000000000000000002521270554304000161160ustar00rootroot00000000000000TODO for Net_PublicSuffix ========================= * speed up reading of public suffix list. it's too slow! * get the package into PEAR for alternate distribution. php-net-publicsuffix-0.2/test.php000077500000000000000000000016771270554304000171350ustar00rootroot00000000000000#!/usr/bin/php 0) exit(1); else exit(0); /* * Local Variables: * indent-tabs-mode: nil * c-basic-offset: 2 * End: */