75    public static function getIP(
bool $force = 
false) : string|false{
 
   78        }elseif(self::$ip !== 
false && !$force){
 
   84            return self::$ip = $ip->getBody();
 
   88        if($ip !== 
null && preg_match(
'#Current IP Address\: ([0-9a-fA-F\:\.]*)#', trim(strip_tags($ip->getBody())), $matches) > 0){
 
   89            return self::$ip = $matches[1];
 
   93        if($ip !== 
null && preg_match(
'#">([0-9a-fA-F\:\.]*)</span>#', $ip->getBody(), $matches) > 0){
 
   94            return self::$ip = $matches[1];
 
   98        if($ip !== 
null && preg_match(
'#Your IP address is ([0-9a-fA-F\:\.]*)#', $ip->getBody(), $matches) > 0){
 
   99            return self::$ip = $matches[1];
 
  103        if($ip !== 
null && ($addr = trim($ip->getBody())) !== 
""){
 
  104            return self::$ip = $addr;
 
 
  117        $sock = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
 
  119            throw new InternetException(
"Failed to get internal IP: " . trim(socket_strerror(socket_last_error())));
 
  122            if(!@socket_connect($sock, 
"8.8.8.8", 65534)){
 
  123                throw new InternetException(
"Failed to get internal IP: " . trim(socket_strerror(socket_last_error($sock))));
 
  125            if(!@socket_getsockname($sock, $name)){
 
  126                throw new InternetException(
"Failed to get internal IP: " . trim(socket_strerror(socket_last_error($sock))));
 
 
  172            return self::simpleCurl($page, $timeout, $extraHeaders, [
 
  174                CURLOPT_POSTFIELDS => $args
 
  177            $err = $ex->getMessage();
 
 
  196    public static function simpleCurl(
string $page, 
float $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?\Closure $onSuccess = 
null) : 
InternetRequestResult{
 
  201        $ch = curl_init($page);
 
  206        curl_setopt_array($ch, $extraOpts + [
 
  207            CURLOPT_SSL_VERIFYPEER => 
false,
 
  208            CURLOPT_SSL_VERIFYHOST => 2,
 
  209            CURLOPT_FORBID_REUSE => 1,
 
  210            CURLOPT_FRESH_CONNECT => 1,
 
  211            CURLOPT_AUTOREFERER => 
true,
 
  212            CURLOPT_FOLLOWLOCATION => 
true,
 
  213            CURLOPT_RETURNTRANSFER => 
true,
 
  214            CURLOPT_CONNECTTIMEOUT_MS => (
int) ($timeout * 1000),
 
  215            CURLOPT_TIMEOUT_MS => (
int) ($timeout * 1000),
 
  216            CURLOPT_HTTPHEADER => array_merge([
"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0 " . VersionInfo::NAME . 
"/" . VersionInfo::VERSION()->getFullVersion(
true)], $extraHeaders),
 
  217            CURLOPT_HEADER => 
true 
  219        $raw = curl_exec($ch);
 
  221            throw new InternetException(curl_error($ch));
 
  223        if(!is_string($raw)) 
throw new AssumptionFailedError(
"curl_exec() should return string|false when CURLOPT_RETURNTRANSFER is set");
 
  224        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 
  225        $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
 
  226        $rawHeaders = substr($raw, 0, $headerSize);
 
  227        $body = substr($raw, $headerSize);
 
  230        foreach(explode(
"\r\n\r\n", $rawHeaders, limit: PHP_INT_MAX) as $rawHeaderGroup){
 
  232            foreach(explode(
"\r\n", $rawHeaderGroup, limit: PHP_INT_MAX) as $line){
 
  233                $nameValue = explode(
":", $line, 2);
 
  234                if(isset($nameValue[1])){
 
  235                    $headerGroup[trim(strtolower($nameValue[0]))] = trim($nameValue[1]);
 
  238            $headers[] = $headerGroup;
 
  240        if($onSuccess !== 
null){
 
  243        return new InternetRequestResult($headers, $body, $httpCode);