PocketMine-MP 5.15.1 git-5ef247620a7c6301a849b54e5ef1009217729fc8
Internet.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\utils;
25
27use function array_merge;
28use function curl_close;
29use function curl_error;
30use function curl_exec;
31use function curl_getinfo;
32use function curl_init;
33use function curl_setopt_array;
34use function explode;
35use function is_string;
36use function preg_match;
37use function socket_close;
38use function socket_connect;
39use function socket_create;
40use function socket_getsockname;
41use function socket_last_error;
42use function socket_strerror;
43use function strip_tags;
44use function strtolower;
45use function substr;
46use function trim;
47use const AF_INET;
48use const CURLINFO_HEADER_SIZE;
49use const CURLINFO_HTTP_CODE;
50use const CURLOPT_AUTOREFERER;
51use const CURLOPT_CONNECTTIMEOUT_MS;
52use const CURLOPT_FOLLOWLOCATION;
53use const CURLOPT_FORBID_REUSE;
54use const CURLOPT_FRESH_CONNECT;
55use const CURLOPT_HEADER;
56use const CURLOPT_HTTPHEADER;
57use const CURLOPT_POST;
58use const CURLOPT_POSTFIELDS;
59use const CURLOPT_RETURNTRANSFER;
60use const CURLOPT_SSL_VERIFYHOST;
61use const CURLOPT_SSL_VERIFYPEER;
62use const CURLOPT_TIMEOUT_MS;
63use const SOCK_DGRAM;
64use const SOL_UDP;
65
67 public static string|false $ip = false;
68 public static bool $online = true;
69
75 public static function getIP(bool $force = false) : string|false{
76 if(!self::$online){
77 return false;
78 }elseif(self::$ip !== false && !$force){
79 return self::$ip;
80 }
81
82 $ip = self::getURL("http://api.ipify.org/");
83 if($ip !== null){
84 return self::$ip = $ip->getBody();
85 }
86
87 $ip = self::getURL("http://checkip.dyndns.org/");
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];
90 }
91
92 $ip = self::getURL("http://www.checkip.org/");
93 if($ip !== null && preg_match('#">([0-9a-fA-F\:\.]*)</span>#', $ip->getBody(), $matches) > 0){
94 return self::$ip = $matches[1];
95 }
96
97 $ip = self::getURL("http://checkmyip.org/");
98 if($ip !== null && preg_match('#Your IP address is ([0-9a-fA-F\:\.]*)#', $ip->getBody(), $matches) > 0){
99 return self::$ip = $matches[1];
100 }
101
102 $ip = self::getURL("http://ifconfig.me/ip");
103 if($ip !== null && ($addr = trim($ip->getBody())) != ""){
104 return self::$ip = $addr;
105 }
106
107 return false;
108 }
109
116 public static function getInternalIP() : string{
117 $sock = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
118 if($sock === false){
119 throw new InternetException("Failed to get internal IP: " . trim(socket_strerror(socket_last_error())));
120 }
121 try{
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))));
124 }
125 if(!@socket_getsockname($sock, $name)){
126 throw new InternetException("Failed to get internal IP: " . trim(socket_strerror(socket_last_error($sock))));
127 }
128 return $name;
129 }finally{
130 socket_close($sock);
131 }
132 }
133
147 public static function getURL(string $page, int $timeout = 10, array $extraHeaders = [], &$err = null) : ?InternetRequestResult{
148 try{
149 return self::simpleCurl($page, $timeout, $extraHeaders);
150 }catch(InternetException $ex){
151 $err = $ex->getMessage();
152 return null;
153 }
154 }
155
170 public static function postURL(string $page, array|string $args, int $timeout = 10, array $extraHeaders = [], &$err = null) : ?InternetRequestResult{
171 try{
172 return self::simpleCurl($page, $timeout, $extraHeaders, [
173 CURLOPT_POST => 1,
174 CURLOPT_POSTFIELDS => $args
175 ]);
176 }catch(InternetException $ex){
177 $err = $ex->getMessage();
178 return null;
179 }
180 }
181
196 public static function simpleCurl(string $page, float $timeout = 10, array $extraHeaders = [], array $extraOpts = [], ?\Closure $onSuccess = null) : InternetRequestResult{
197 if(!self::$online){
198 throw new InternetException("Cannot execute web request while offline");
199 }
200
201 $ch = curl_init($page);
202 if($ch === false){
203 throw new InternetException("Unable to create new cURL session");
204 }
205
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
218 ]);
219 try{
220 $raw = curl_exec($ch);
221 if($raw === false){
222 throw new InternetException(curl_error($ch));
223 }
224 if(!is_string($raw)) throw new AssumptionFailedError("curl_exec() should return string|false when CURLOPT_RETURNTRANSFER is set");
225 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
226 $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
227 $rawHeaders = substr($raw, 0, $headerSize);
228 $body = substr($raw, $headerSize);
229 $headers = [];
230 foreach(explode("\r\n\r\n", $rawHeaders) as $rawHeaderGroup){
231 $headerGroup = [];
232 foreach(explode("\r\n", $rawHeaderGroup) as $line){
233 $nameValue = explode(":", $line, 2);
234 if(isset($nameValue[1])){
235 $headerGroup[trim(strtolower($nameValue[0]))] = trim($nameValue[1]);
236 }
237 }
238 $headers[] = $headerGroup;
239 }
240 if($onSuccess !== null){
241 $onSuccess($ch);
242 }
243 return new InternetRequestResult($headers, $body, $httpCode);
244 }finally{
245 curl_close($ch);
246 }
247 }
248}
static getIP(bool $force=false)
Definition: Internet.php:75
static simpleCurl(string $page, float $timeout=10, array $extraHeaders=[], array $extraOpts=[], ?\Closure $onSuccess=null)
Definition: Internet.php:196
static getURL(string $page, int $timeout=10, array $extraHeaders=[], &$err=null)
Definition: Internet.php:147
static postURL(string $page, array|string $args, int $timeout=10, array $extraHeaders=[], &$err=null)
Definition: Internet.php:170