diff options
author | marvin-borner@live.com | 2018-04-10 21:50:16 +0200 |
---|---|---|
committer | marvin-borner@live.com | 2018-04-10 21:54:48 +0200 |
commit | fc9401f04a3aca5abb22f87ebc210de8afe11d32 (patch) | |
tree | b0b310f3581764ec3955f4e496a05137a32951c3 /assets/php/vendor/react/dns/src/Config | |
parent | 286d643180672f20526f3dc3bd19d7b751e2fa97 (diff) |
Initial Commit
Diffstat (limited to 'assets/php/vendor/react/dns/src/Config')
3 files changed, 351 insertions, 0 deletions
diff --git a/assets/php/vendor/react/dns/src/Config/Config.php b/assets/php/vendor/react/dns/src/Config/Config.php new file mode 100644 index 0000000..c82635d --- /dev/null +++ b/assets/php/vendor/react/dns/src/Config/Config.php @@ -0,0 +1,127 @@ +<?php + +namespace React\Dns\Config; + +use RuntimeException; + +class Config +{ + /** + * Loads the system DNS configuration + * + * Note that this method may block while loading its internal files and/or + * commands and should thus be used with care! While this should be + * relatively fast for most systems, it remains unknown if this may block + * under certain circumstances. In particular, this method should only be + * executed before the loop starts, not while it is running. + * + * Note that this method will try to access its files and/or commands and + * try to parse its output. Currently, this will only parse valid nameserver + * entries from its output and will ignore all other output without + * complaining. + * + * Note that the previous section implies that this may return an empty + * `Config` object if no valid nameserver entries can be found. + * + * @return self + * @codeCoverageIgnore + */ + public static function loadSystemConfigBlocking() + { + // Use WMIC output on Windows + if (DIRECTORY_SEPARATOR === '\\') { + return self::loadWmicBlocking(); + } + + // otherwise (try to) load from resolv.conf + try { + return self::loadResolvConfBlocking(); + } catch (RuntimeException $ignored) { + // return empty config if parsing fails (file not found) + return new self(); + } + } + + /** + * Loads a resolv.conf file (from the given path or default location) + * + * Note that this method blocks while loading the given path and should + * thus be used with care! While this should be relatively fast for normal + * resolv.conf files, this may be an issue if this file is located on a slow + * device or contains an excessive number of entries. In particular, this + * method should only be executed before the loop starts, not while it is + * running. + * + * Note that this method will throw if the given file can not be loaded, + * such as if it is not readable or does not exist. In particular, this file + * is not available on Windows. + * + * Currently, this will only parse valid "nameserver X" lines from the + * given file contents. Lines can be commented out with "#" and ";" and + * invalid lines will be ignored without complaining. See also + * `man resolv.conf` for more details. + * + * Note that the previous section implies that this may return an empty + * `Config` object if no valid "nameserver X" lines can be found. See also + * `man resolv.conf` which suggests that the DNS server on the localhost + * should be used in this case. This is left up to higher level consumers + * of this API. + * + * @param ?string $path (optional) path to resolv.conf file or null=load default location + * @return self + * @throws RuntimeException if the path can not be loaded (does not exist) + */ + public static function loadResolvConfBlocking($path = null) + { + if ($path === null) { + $path = '/etc/resolv.conf'; + } + + $contents = @file_get_contents($path); + if ($contents === false) { + throw new RuntimeException('Unable to load resolv.conf file "' . $path . '"'); + } + + preg_match_all('/^nameserver\s+(\S+)\s*$/m', $contents, $matches); + + $config = new self(); + $config->nameservers = $matches[1]; + + return $config; + } + + /** + * Loads the DNS configurations from Windows's WMIC (from the given command or default command) + * + * Note that this method blocks while loading the given command and should + * thus be used with care! While this should be relatively fast for normal + * WMIC commands, it remains unknown if this may block under certain + * circumstances. In particular, this method should only be executed before + * the loop starts, not while it is running. + * + * Note that this method will only try to execute the given command try to + * parse its output, irrespective of whether this command exists. In + * particular, this command is only available on Windows. Currently, this + * will only parse valid nameserver entries from the command output and will + * ignore all other output without complaining. + * + * Note that the previous section implies that this may return an empty + * `Config` object if no valid nameserver entries can be found. + * + * @param ?string $command (advanced) should not be given (NULL) unless you know what you're doing + * @return self + * @link https://ss64.com/nt/wmic.html + */ + public static function loadWmicBlocking($command = null) + { + $contents = shell_exec($command === null ? 'wmic NICCONFIG get "DNSServerSearchOrder" /format:CSV' : $command); + preg_match_all('/(?<=[{;,"])([\da-f.:]{4,})(?=[};,"])/i', $contents, $matches); + + $config = new self(); + $config->nameservers = $matches[1]; + + return $config; + } + + public $nameservers = array(); +} diff --git a/assets/php/vendor/react/dns/src/Config/FilesystemFactory.php b/assets/php/vendor/react/dns/src/Config/FilesystemFactory.php new file mode 100644 index 0000000..68cec3e --- /dev/null +++ b/assets/php/vendor/react/dns/src/Config/FilesystemFactory.php @@ -0,0 +1,73 @@ +<?php + +namespace React\Dns\Config; + +use React\EventLoop\LoopInterface; +use React\Promise; +use React\Promise\Deferred; +use React\Stream\ReadableResourceStream; +use React\Stream\Stream; + +/** + * @deprecated + * @see Config see Config class instead. + */ +class FilesystemFactory +{ + private $loop; + + public function __construct(LoopInterface $loop) + { + $this->loop = $loop; + } + + public function create($filename) + { + return $this + ->loadEtcResolvConf($filename) + ->then(array($this, 'parseEtcResolvConf')); + } + + /** + * @param string $contents + * @return Promise + * @deprecated see Config instead + */ + public function parseEtcResolvConf($contents) + { + return Promise\resolve(Config::loadResolvConfBlocking( + 'data://text/plain;base64,' . base64_encode($contents) + )); + } + + public function loadEtcResolvConf($filename) + { + if (!file_exists($filename)) { + return Promise\reject(new \InvalidArgumentException("The filename for /etc/resolv.conf given does not exist: $filename")); + } + + try { + $deferred = new Deferred(); + + $fd = fopen($filename, 'r'); + stream_set_blocking($fd, 0); + + $contents = ''; + + $stream = class_exists('React\Stream\ReadableResourceStream') ? new ReadableResourceStream($fd, $this->loop) : new Stream($fd, $this->loop); + $stream->on('data', function ($data) use (&$contents) { + $contents .= $data; + }); + $stream->on('end', function () use (&$contents, $deferred) { + $deferred->resolve($contents); + }); + $stream->on('error', function ($error) use ($deferred) { + $deferred->reject($error); + }); + + return $deferred->promise(); + } catch (\Exception $e) { + return Promise\reject($e); + } + } +} diff --git a/assets/php/vendor/react/dns/src/Config/HostsFile.php b/assets/php/vendor/react/dns/src/Config/HostsFile.php new file mode 100644 index 0000000..5b6277e --- /dev/null +++ b/assets/php/vendor/react/dns/src/Config/HostsFile.php @@ -0,0 +1,151 @@ +<?php + +namespace React\Dns\Config; + +use RuntimeException; + +/** + * Represents a static hosts file which maps hostnames to IPs + * + * Hosts files are used on most systems to avoid actually hitting the DNS for + * certain common hostnames. + * + * Most notably, this file usually contains an entry to map "localhost" to the + * local IP. Windows is a notable exception here, as Windows does not actually + * include "localhost" in this file by default. To compensate for this, this + * class may explicitly be wrapped in another HostsFile instance which + * hard-codes these entries for Windows (see also Factory). + * + * This class mostly exists to abstract the parsing/extraction process so this + * can be replaced with a faster alternative in the future. + */ +class HostsFile +{ + /** + * Returns the default path for the hosts file on this system + * + * @return string + * @codeCoverageIgnore + */ + public static function getDefaultPath() + { + // use static path for all Unix-based systems + if (DIRECTORY_SEPARATOR !== '\\') { + return '/etc/hosts'; + } + + // Windows actually stores the path in the registry under + // \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DataBasePath + $path = '%SystemRoot%\\system32\drivers\etc\hosts'; + + $base = getenv('SystemRoot'); + if ($base === false) { + $base = 'C:\\Windows'; + } + + return str_replace('%SystemRoot%', $base, $path); + } + + /** + * Loads a hosts file (from the given path or default location) + * + * Note that this method blocks while loading the given path and should + * thus be used with care! While this should be relatively fast for normal + * hosts file, this may be an issue if this file is located on a slow device + * or contains an excessive number of entries. In particular, this method + * should only be executed before the loop starts, not while it is running. + * + * @param ?string $path (optional) path to hosts file or null=load default location + * @return self + * @throws RuntimeException if the path can not be loaded (does not exist) + */ + public static function loadFromPathBlocking($path = null) + { + if ($path === null) { + $path = self::getDefaultPath(); + } + + $contents = @file_get_contents($path); + if ($contents === false) { + throw new RuntimeException('Unable to load hosts file "' . $path . '"'); + } + + return new self($contents); + } + + /** + * Instantiate new hosts file with the given hosts file contents + * + * @param string $contents + */ + public function __construct($contents) + { + // remove all comments from the contents + $contents = preg_replace('/[ \t]*#.*/', '', strtolower($contents)); + + $this->contents = $contents; + } + + /** + * Returns all IPs for the given hostname + * + * @param string $name + * @return string[] + */ + public function getIpsForHost($name) + { + $name = strtolower($name); + + $ips = array(); + foreach (preg_split('/\r?\n/', $this->contents) as $line) { + $parts = preg_split('/\s+/', $line); + $ip = array_shift($parts); + if ($parts && array_search($name, $parts) !== false) { + // remove IPv6 zone ID (`fe80::1%lo0` => `fe80:1`) + if (strpos($ip, ':') !== false && ($pos = strpos($ip, '%')) !== false) { + $ip = substr($ip, 0, $pos); + } + + if (@inet_pton($ip) !== false) { + $ips[] = $ip; + } + } + } + + return $ips; + } + + /** + * Returns all hostnames for the given IPv4 or IPv6 address + * + * @param string $ip + * @return string[] + */ + public function getHostsForIp($ip) + { + // check binary representation of IP to avoid string case and short notation + $ip = @inet_pton($ip); + if ($ip === false) { + return array(); + } + + $names = array(); + foreach (preg_split('/\r?\n/', $this->contents) as $line) { + $parts = preg_split('/\s+/', $line, null, PREG_SPLIT_NO_EMPTY); + $addr = array_shift($parts); + + // remove IPv6 zone ID (`fe80::1%lo0` => `fe80:1`) + if (strpos($addr, ':') !== false && ($pos = strpos($addr, '%')) !== false) { + $addr = substr($addr, 0, $pos); + } + + if (@inet_pton($addr) === $ip) { + foreach ($parts as $part) { + $names[] = $part; + } + } + } + + return $names; + } +} |