communication.func.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. <?php
  2. /**
  3. * [WeEngine System] Copyright (c) 2014 WE7.CC
  4. * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
  5. */
  6. defined('IN_IA') or exit('Access Denied');
  7. function ihttp_request($url, $post = '', $extra = array(), $timeout = 60) {
  8. if (function_exists('curl_init') && function_exists('curl_exec') && $timeout > 0) {
  9. $ch = ihttp_build_curl($url, $post, $extra, $timeout);
  10. if (is_error($ch)) {
  11. return $ch;
  12. }
  13. $data = curl_exec($ch);
  14. $status = curl_getinfo($ch);
  15. $errno = curl_errno($ch);
  16. $error = curl_error($ch);
  17. curl_close($ch);
  18. if ($errno || empty($data)) {
  19. return error($errno, $error);
  20. } else {
  21. return ihttp_response_parse($data);
  22. }
  23. }
  24. $urlset = ihttp_parse_url($url, true);
  25. if (!empty($urlset['ip'])) {
  26. $urlset['host'] = $urlset['ip'];
  27. }
  28. $body = ihttp_build_httpbody($url, $post, $extra);
  29. if ('https' == $urlset['scheme']) {
  30. $fp = ihttp_socketopen('ssl://' . $urlset['host'], $urlset['port'], $errno, $error);
  31. } else {
  32. $fp = ihttp_socketopen($urlset['host'], $urlset['port'], $errno, $error);
  33. }
  34. stream_set_blocking($fp, $timeout > 0 ? true : false);
  35. stream_set_timeout($fp, ini_get('default_socket_timeout'));
  36. if (!$fp) {
  37. return error(1, $error);
  38. } else {
  39. fwrite($fp, $body);
  40. $content = '';
  41. if ($timeout > 0) {
  42. while (!feof($fp)) {
  43. $content .= fgets($fp, 512);
  44. }
  45. }
  46. fclose($fp);
  47. return ihttp_response_parse($content, true);
  48. }
  49. }
  50. function ihttp_get($url) {
  51. return ihttp_request($url);
  52. }
  53. function ihttp_post($url, $data) {
  54. $headers = array('Content-Type' => 'application/x-www-form-urlencoded');
  55. return ihttp_request($url, $data, $headers);
  56. }
  57. function ihttp_multi_request($urls, $posts = array(), $extra = array(), $timeout = 60) {
  58. if (!is_array($urls)) {
  59. return error(1, '请使用ihttp_request函数');
  60. }
  61. $curl_multi = curl_multi_init();
  62. $curl_client = $response = array();
  63. foreach ($urls as $i => $url) {
  64. if (isset($posts[$i]) && is_array($posts[$i])) {
  65. $post = $posts[$i];
  66. } else {
  67. $post = $posts;
  68. }
  69. if (!empty($url)) {
  70. $curl = ihttp_build_curl($url, $post, $extra, $timeout);
  71. if (is_error($curl)) {
  72. continue;
  73. }
  74. if (CURLM_OK === curl_multi_add_handle($curl_multi, $curl)) {
  75. $curl_client[] = $curl;
  76. }
  77. }
  78. }
  79. if (!empty($curl_client)) {
  80. $active = null;
  81. do {
  82. $mrc = curl_multi_exec($curl_multi, $active);
  83. } while (CURLM_CALL_MULTI_PERFORM == $mrc);
  84. while ($active && CURLM_OK == $mrc) {
  85. do {
  86. $mrc = curl_multi_exec($curl_multi, $active);
  87. } while (CURLM_CALL_MULTI_PERFORM == $mrc);
  88. }
  89. }
  90. foreach ($curl_client as $i => $curl) {
  91. $response[$i] = curl_multi_getcontent($curl);
  92. curl_multi_remove_handle($curl_multi, $curl);
  93. }
  94. curl_multi_close($curl_multi);
  95. return $response;
  96. }
  97. function ihttp_socketopen($hostname, $port, &$errno, &$errstr, $timeout = 15) {
  98. $fp = '';
  99. $port = !empty($port) ? $port : 80;
  100. if (function_exists('fsockopen')) {
  101. $fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout);
  102. } elseif (function_exists('pfsockopen')) {
  103. $fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout);
  104. } elseif (function_exists('stream_socket_client')) {
  105. $fp = @stream_socket_client($hostname . ':' . $port, $errno, $errstr, $timeout);
  106. }
  107. return $fp;
  108. }
  109. function ihttp_response_parse($data, $chunked = false) {
  110. $rlt = array();
  111. $pos = strpos($data, "\r\n\r\n");
  112. $split1[0] = substr($data, 0, $pos);
  113. $split1[1] = substr($data, $pos + 4, strlen($data));
  114. $split2 = explode("\r\n", $split1[0], 2);
  115. preg_match('/^(\S+) (\S+) (.*)$/', $split2[0], $matches);
  116. $rlt['code'] = !empty($matches[2]) ? $matches[2] : 200;
  117. $rlt['status'] = !empty($matches[3]) ? $matches[3] : 'OK';
  118. $rlt['responseline'] = !empty($split2[0]) ? $split2[0] : '';
  119. $header = !empty($split2[1]) ? explode("\r\n", $split2[1]) : array();
  120. $isgzip = false;
  121. $ischunk = false;
  122. foreach ($header as $v) {
  123. $pos = strpos($v, ':');
  124. $key = substr($v, 0, $pos);
  125. $value = trim(substr($v, $pos + 1));
  126. if (isset($rlt['headers'][$key]) && is_array($rlt['headers'][$key])) {
  127. $rlt['headers'][$key][] = $value;
  128. } elseif (!empty($rlt['headers'][$key])) {
  129. $temp = $rlt['headers'][$key];
  130. unset($rlt['headers'][$key]);
  131. $rlt['headers'][$key][] = $temp;
  132. $rlt['headers'][$key][] = $value;
  133. } else {
  134. $rlt['headers'][$key] = $value;
  135. }
  136. if (!$isgzip && 'content-encoding' == strtolower($key) && 'gzip' == strtolower($value)) {
  137. $isgzip = true;
  138. }
  139. if (!$ischunk && 'transfer-encoding' == strtolower($key) && 'chunked' == strtolower($value)) {
  140. $ischunk = true;
  141. }
  142. }
  143. if ($chunked && $ischunk) {
  144. $rlt['content'] = ihttp_response_parse_unchunk($split1[1]);
  145. } else {
  146. $rlt['content'] = $split1[1];
  147. }
  148. if ($isgzip && function_exists('gzdecode')) {
  149. $rlt['content'] = gzdecode($rlt['content']);
  150. }
  151. $rlt['meta'] = $data;
  152. if ('100' == $rlt['code']) {
  153. return ihttp_response_parse($rlt['content']);
  154. }
  155. return $rlt;
  156. }
  157. function ihttp_response_parse_unchunk($str = null) {
  158. if (!is_string($str) or strlen($str) < 1) {
  159. return false;
  160. }
  161. $eol = "\r\n";
  162. $add = strlen($eol);
  163. $tmp = $str;
  164. $str = '';
  165. do {
  166. $tmp = ltrim($tmp);
  167. $pos = strpos($tmp, $eol);
  168. if (false === $pos) {
  169. return false;
  170. }
  171. $len = hexdec(substr($tmp, 0, $pos));
  172. if (!is_numeric($len) or $len < 0) {
  173. return false;
  174. }
  175. $str .= substr($tmp, ($pos + $add), $len);
  176. $tmp = substr($tmp, ($len + $pos + $add));
  177. $check = trim($tmp);
  178. } while (!empty($check));
  179. unset($tmp);
  180. return $str;
  181. }
  182. function ihttp_parse_url($url, $set_default_port = false) {
  183. if (empty($url)) {
  184. return error(1);
  185. }
  186. $urlset = parse_url($url);
  187. if (!empty($urlset['scheme']) && !in_array($urlset['scheme'], array('http', 'https'))) {
  188. return error(1, '只能使用 http 及 https 协议');
  189. }
  190. if (empty($urlset['path'])) {
  191. $urlset['path'] = '/';
  192. }
  193. if (!empty($urlset['query'])) {
  194. $urlset['query'] = "?{$urlset['query']}";
  195. }
  196. if (strexists($url, 'https://') && !extension_loaded('openssl')) {
  197. if (!extension_loaded('openssl')) {
  198. return error(1, '请开启您PHP环境的openssl', '');
  199. }
  200. }
  201. if (empty($urlset['host'])) {
  202. $current_url = parse_url($GLOBALS['_W']['siteroot']);
  203. $urlset['host'] = $current_url['host'];
  204. $urlset['scheme'] = $current_url['scheme'];
  205. $urlset['path'] = $current_url['path'] . 'web/' . str_replace('./', '', $urlset['path']);
  206. $urlset['ip'] = '127.0.0.1';
  207. } elseif (!ihttp_allow_host($urlset['host'])) {
  208. return error(1, 'host 非法');
  209. }
  210. if ($set_default_port && empty($urlset['port'])) {
  211. $urlset['port'] = 'https' == $urlset['scheme'] ? '443' : '80';
  212. }
  213. return $urlset;
  214. }
  215. function ihttp_allow_host($host) {
  216. global $_W;
  217. if (strexists($host, '@')) {
  218. return false;
  219. }
  220. $pattern = '/^(10|172|192|127)/';
  221. if (preg_match($pattern, $host) && isset($_W['setting']['ip_white_list'])) {
  222. $ip_white_list = $_W['setting']['ip_white_list'];
  223. if ($ip_white_list && isset($ip_white_list[$host]) && !$ip_white_list[$host]['status']) {
  224. return false;
  225. }
  226. }
  227. return true;
  228. }
  229. function ihttp_build_curl($url, $post, $extra, $timeout) {
  230. if (!function_exists('curl_init') || !function_exists('curl_exec')) {
  231. return error(1, 'curl扩展未开启');
  232. }
  233. $urlset = ihttp_parse_url($url);
  234. if (is_error($urlset)) {
  235. return $urlset;
  236. }
  237. if (!empty($urlset['ip'])) {
  238. $extra['ip'] = $urlset['ip'];
  239. }
  240. $ch = curl_init();
  241. if (!empty($extra['ip'])) {
  242. $extra['Host'] = $urlset['host'];
  243. $urlset['host'] = $extra['ip'];
  244. unset($extra['ip']);
  245. }
  246. curl_setopt($ch, CURLOPT_URL, $urlset['scheme'] . '://' . $urlset['host'] . (empty($urlset['port']) || '80' == $urlset['port'] ? '' : ':' . $urlset['port']) . $urlset['path'] . (!empty($urlset['query']) ? $urlset['query'] : ''));
  247. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  248. @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
  249. curl_setopt($ch, CURLOPT_HEADER, 1);
  250. @curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  251. if ($post) {
  252. if (is_array($post)) {
  253. $filepost = false;
  254. foreach ($post as $name => &$value) {
  255. if (version_compare(phpversion(), '5.5') >= 0 && is_string($value) && '@' == substr($value, 0, 1)) {
  256. $post[$name] = new CURLFile(ltrim($value, '@'));
  257. }
  258. if ((is_string($value) && '@' == substr($value, 0, 1)) || (class_exists('CURLFile') && $value instanceof CURLFile)) {
  259. $filepost = true;
  260. }
  261. }
  262. if (!$filepost) {
  263. $post = http_build_query($post);
  264. }
  265. }
  266. curl_setopt($ch, CURLOPT_POST, 1);
  267. curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  268. }
  269. if (!empty($GLOBALS['_W']['config']['setting']['proxy'])) {
  270. $urls = parse_url($GLOBALS['_W']['config']['setting']['proxy']['host']);
  271. if (!empty($urls['host'])) {
  272. curl_setopt($ch, CURLOPT_PROXY, "{$urls['host']}:{$urls['port']}");
  273. $proxytype = 'CURLPROXY_' . strtoupper($urls['scheme']);
  274. if (!empty($urls['scheme']) && defined($proxytype)) {
  275. curl_setopt($ch, CURLOPT_PROXYTYPE, constant($proxytype));
  276. } else {
  277. curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
  278. curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
  279. }
  280. if (!empty($GLOBALS['_W']['config']['setting']['proxy']['auth'])) {
  281. curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['_W']['config']['setting']['proxy']['auth']);
  282. }
  283. }
  284. }
  285. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  286. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  287. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  288. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  289. curl_setopt($ch, CURLOPT_SSLVERSION, 1);
  290. if (defined('CURL_SSLVERSION_TLSv1')) {
  291. curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
  292. }
  293. curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1');
  294. if (!empty($extra) && is_array($extra)) {
  295. $headers = array();
  296. foreach ($extra as $opt => $value) {
  297. if (strexists($opt, 'CURLOPT_')) {
  298. curl_setopt($ch, constant($opt), $value);
  299. } elseif (is_numeric($opt)) {
  300. curl_setopt($ch, $opt, $value);
  301. } else {
  302. $headers[] = "{$opt}: {$value}";
  303. }
  304. }
  305. if (!empty($headers)) {
  306. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  307. }
  308. }
  309. return $ch;
  310. }
  311. function ihttp_build_httpbody($url, $post, $extra) {
  312. $urlset = ihttp_parse_url($url, true);
  313. if (is_error($urlset)) {
  314. return $urlset;
  315. }
  316. if (!empty($urlset['ip'])) {
  317. $extra['ip'] = $urlset['ip'];
  318. }
  319. $body = '';
  320. if (!empty($post) && is_array($post)) {
  321. $filepost = false;
  322. $boundary = random(40);
  323. foreach ($post as $name => &$value) {
  324. if ((is_string($value) && '@' == substr($value, 0, 1)) && file_exists(ltrim($value, '@'))) {
  325. $filepost = true;
  326. $file = ltrim($value, '@');
  327. $body .= "--$boundary\r\n";
  328. $body .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . basename($file) . '"; Content-Type: application/octet-stream' . "\r\n\r\n";
  329. $body .= file_get_contents($file) . "\r\n";
  330. } else {
  331. $body .= "--$boundary\r\n";
  332. $body .= 'Content-Disposition: form-data; name="' . $name . '"' . "\r\n\r\n";
  333. $body .= $value . "\r\n";
  334. }
  335. }
  336. if (!$filepost) {
  337. $body = http_build_query($post, '', '&');
  338. } else {
  339. $body .= "--$boundary\r\n";
  340. }
  341. }
  342. $method = empty($post) ? 'GET' : 'POST';
  343. $fdata = "{$method} {$urlset['path']}{$urlset['query']} HTTP/1.1\r\n";
  344. $fdata .= "Accept: */*\r\n";
  345. $fdata .= "Accept-Language: zh-cn\r\n";
  346. if ('POST' == $method) {
  347. $fdata .= empty($filepost) ? "Content-Type: application/x-www-form-urlencoded\r\n" : "Content-Type: multipart/form-data; boundary=$boundary\r\n";
  348. }
  349. $fdata .= "Host: {$urlset['host']}\r\n";
  350. $fdata .= "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\n";
  351. if (function_exists('gzdecode')) {
  352. $fdata .= "Accept-Encoding: gzip, deflate\r\n";
  353. }
  354. $fdata .= "Connection: close\r\n";
  355. if (!empty($extra) && is_array($extra)) {
  356. foreach ($extra as $opt => $value) {
  357. if (!strexists($opt, 'CURLOPT_')) {
  358. $fdata .= "{$opt}: {$value}\r\n";
  359. }
  360. }
  361. }
  362. if ($body) {
  363. $fdata .= 'Content-Length: ' . strlen($body) . "\r\n\r\n{$body}";
  364. } else {
  365. $fdata .= "\r\n";
  366. }
  367. return $fdata;
  368. }
  369. function ihttp_email($to, $subject, $body, $global = false) {
  370. static $mailer;
  371. set_time_limit(0);
  372. if (empty($mailer)) {
  373. if (!class_exists('PHPMailer')) {
  374. load()->library('phpmailer');
  375. }
  376. $mailer = new PHPMailer();
  377. global $_W;
  378. $config = $GLOBALS['_W']['setting']['mail'];
  379. if (!$global) {
  380. $row = pdo_get('uni_settings', array('uniacid' => $_W['uniacid']), array('notify'));
  381. $row['notify'] = @iunserializer($row['notify']);
  382. if (!empty($row['notify']) && !empty($row['notify']['mail'])) {
  383. $config = $row['notify']['mail'];
  384. }
  385. }
  386. $config['charset'] = 'utf-8';
  387. if ($config['smtp']['type'] == '163') {
  388. $config['smtp']['server'] = 'smtp.163.com';
  389. $config['smtp']['port'] = 25;
  390. } elseif ($config['smtp']['type'] == 'qq') {
  391. $config['smtp']['server'] = 'ssl://smtp.qq.com';
  392. $config['smtp']['port'] = 465;
  393. } else {
  394. if (!empty($config['smtp']['authmode'])) {
  395. $config['smtp']['server'] = 'ssl://' . $config['smtp']['server'];
  396. }
  397. }
  398. if (!empty($config['smtp']['authmode'])) {
  399. if (!extension_loaded('openssl')) {
  400. return error(1, '请开启 php_openssl 扩展!');
  401. }
  402. }
  403. $mailer->signature = $config['signature'];
  404. $mailer->isSMTP();
  405. $mailer->CharSet = $config['charset'];
  406. $mailer->Host = $config['smtp']['server'];
  407. $mailer->Port = $config['smtp']['port'];
  408. $mailer->SMTPAuth = true;
  409. $mailer->Username = $config['username'];
  410. $mailer->Password = $config['password'];
  411. !empty($config['smtp']['authmode']) && $mailer->SMTPSecure = 'ssl';
  412. $mailer->From = $config['username'];
  413. $mailer->FromName = $config['sender'];
  414. $mailer->isHTML(true);
  415. }
  416. if ($body) {
  417. if (is_array($body)) {
  418. $newbody = '';
  419. foreach ($body as $value) {
  420. if ('@' == substr($value, 0, 1)) {
  421. if (!is_file($file = ltrim($value, '@'))) {
  422. return error(1, $file . ' 附件不存在或非文件!');
  423. }
  424. $mailer->addAttachment($file);
  425. } else {
  426. $newbody .= $value . '\n';
  427. }
  428. }
  429. $body = $newbody;
  430. } else {
  431. if ('@' == substr($body, 0, 1)) {
  432. $mailer->addAttachment(ltrim($body, '@'));
  433. $body = '';
  434. }
  435. }
  436. }
  437. if (!empty($mailer->signature)) {
  438. $body .= htmlspecialchars_decode($mailer->signature);
  439. }
  440. $mailer->Subject = $subject;
  441. $mailer->Body = $body;
  442. $mailer->addAddress($to);
  443. $result = $mailer->send();
  444. $mailer->clearAddresses();
  445. $mailer->clearReplyTos();
  446. if ($result) {
  447. return true;
  448. } else {
  449. return error(1, $mailer->ErrorInfo);
  450. }
  451. }