DnsMock.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bridge\PhpUnit;
  11. /**
  12. * @author Nicolas Grekas <p@tchwork.com>
  13. */
  14. class DnsMock
  15. {
  16. private static $hosts = [];
  17. private static $dnsTypes = [
  18. 'A' => \DNS_A,
  19. 'MX' => \DNS_MX,
  20. 'NS' => \DNS_NS,
  21. 'SOA' => \DNS_SOA,
  22. 'PTR' => \DNS_PTR,
  23. 'CNAME' => \DNS_CNAME,
  24. 'AAAA' => \DNS_AAAA,
  25. 'A6' => \DNS_A6,
  26. 'SRV' => \DNS_SRV,
  27. 'NAPTR' => \DNS_NAPTR,
  28. 'TXT' => \DNS_TXT,
  29. 'HINFO' => \DNS_HINFO,
  30. ];
  31. /**
  32. * Configures the mock values for DNS queries.
  33. *
  34. * @param array $hosts Mocked hosts as keys, arrays of DNS records as returned by dns_get_record() as values
  35. */
  36. public static function withMockedHosts(array $hosts)
  37. {
  38. self::$hosts = $hosts;
  39. }
  40. public static function checkdnsrr($hostname, $type = 'MX')
  41. {
  42. if (!self::$hosts) {
  43. return \checkdnsrr($hostname, $type);
  44. }
  45. if (isset(self::$hosts[$hostname])) {
  46. $type = strtoupper($type);
  47. foreach (self::$hosts[$hostname] as $record) {
  48. if ($record['type'] === $type) {
  49. return true;
  50. }
  51. if ('ANY' === $type && isset(self::$dnsTypes[$record['type']]) && 'HINFO' !== $record['type']) {
  52. return true;
  53. }
  54. }
  55. }
  56. return false;
  57. }
  58. public static function getmxrr($hostname, &$mxhosts, &$weight = null)
  59. {
  60. if (!self::$hosts) {
  61. return \getmxrr($hostname, $mxhosts, $weight);
  62. }
  63. $mxhosts = $weight = [];
  64. if (isset(self::$hosts[$hostname])) {
  65. foreach (self::$hosts[$hostname] as $record) {
  66. if ('MX' === $record['type']) {
  67. $mxhosts[] = $record['host'];
  68. $weight[] = $record['pri'];
  69. }
  70. }
  71. }
  72. return (bool) $mxhosts;
  73. }
  74. public static function gethostbyaddr($ipAddress)
  75. {
  76. if (!self::$hosts) {
  77. return \gethostbyaddr($ipAddress);
  78. }
  79. foreach (self::$hosts as $hostname => $records) {
  80. foreach ($records as $record) {
  81. if ('A' === $record['type'] && $ipAddress === $record['ip']) {
  82. return $hostname;
  83. }
  84. if ('AAAA' === $record['type'] && $ipAddress === $record['ipv6']) {
  85. return $hostname;
  86. }
  87. }
  88. }
  89. return $ipAddress;
  90. }
  91. public static function gethostbyname($hostname)
  92. {
  93. if (!self::$hosts) {
  94. return \gethostbyname($hostname);
  95. }
  96. if (isset(self::$hosts[$hostname])) {
  97. foreach (self::$hosts[$hostname] as $record) {
  98. if ('A' === $record['type']) {
  99. return $record['ip'];
  100. }
  101. }
  102. }
  103. return $hostname;
  104. }
  105. public static function gethostbynamel($hostname)
  106. {
  107. if (!self::$hosts) {
  108. return \gethostbynamel($hostname);
  109. }
  110. $ips = false;
  111. if (isset(self::$hosts[$hostname])) {
  112. $ips = [];
  113. foreach (self::$hosts[$hostname] as $record) {
  114. if ('A' === $record['type']) {
  115. $ips[] = $record['ip'];
  116. }
  117. }
  118. }
  119. return $ips;
  120. }
  121. public static function dns_get_record($hostname, $type = \DNS_ANY, &$authns = null, &$addtl = null, $raw = false)
  122. {
  123. if (!self::$hosts) {
  124. return \dns_get_record($hostname, $type, $authns, $addtl, $raw);
  125. }
  126. $records = false;
  127. if (isset(self::$hosts[$hostname])) {
  128. if (\DNS_ANY === $type) {
  129. $type = \DNS_ALL;
  130. }
  131. $records = [];
  132. foreach (self::$hosts[$hostname] as $record) {
  133. if (isset(self::$dnsTypes[$record['type']]) && (self::$dnsTypes[$record['type']] & $type)) {
  134. $records[] = array_merge(['host' => $hostname, 'class' => 'IN', 'ttl' => 1, 'type' => $record['type']], $record);
  135. }
  136. }
  137. }
  138. return $records;
  139. }
  140. public static function register($class)
  141. {
  142. $self = \get_called_class();
  143. $mockedNs = [substr($class, 0, strrpos($class, '\\'))];
  144. if (0 < strpos($class, '\\Tests\\')) {
  145. $ns = str_replace('\\Tests\\', '\\', $class);
  146. $mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));
  147. } elseif (0 === strpos($class, 'Tests\\')) {
  148. $mockedNs[] = substr($class, 6, strrpos($class, '\\') - 6);
  149. }
  150. foreach ($mockedNs as $ns) {
  151. if (\function_exists($ns.'\checkdnsrr')) {
  152. continue;
  153. }
  154. eval(<<<EOPHP
  155. namespace $ns;
  156. function checkdnsrr(\$host, \$type = 'MX')
  157. {
  158. return \\$self::checkdnsrr(\$host, \$type);
  159. }
  160. function dns_check_record(\$host, \$type = 'MX')
  161. {
  162. return \\$self::checkdnsrr(\$host, \$type);
  163. }
  164. function getmxrr(\$hostname, &\$mxhosts, &\$weight = null)
  165. {
  166. return \\$self::getmxrr(\$hostname, \$mxhosts, \$weight);
  167. }
  168. function dns_get_mx(\$hostname, &\$mxhosts, &\$weight = null)
  169. {
  170. return \\$self::getmxrr(\$hostname, \$mxhosts, \$weight);
  171. }
  172. function gethostbyaddr(\$ipAddress)
  173. {
  174. return \\$self::gethostbyaddr(\$ipAddress);
  175. }
  176. function gethostbyname(\$hostname)
  177. {
  178. return \\$self::gethostbyname(\$hostname);
  179. }
  180. function gethostbynamel(\$hostname)
  181. {
  182. return \\$self::gethostbynamel(\$hostname);
  183. }
  184. function dns_get_record(\$hostname, \$type = DNS_ANY, &\$authns = null, &\$addtl = null, \$raw = false)
  185. {
  186. return \\$self::dns_get_record(\$hostname, \$type, \$authns, \$addtl, \$raw);
  187. }
  188. EOPHP
  189. );
  190. }
  191. }
  192. }