PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/functions.php

http://github.com/sjparkinson/isitup
PHP | 640 lines | 405 code | 78 blank | 157 comment | 63 complexity | 58443cb263c2a46690db8673fb1443f8 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /**
  3. * Generates a domain, with or without a port.
  4. *
  5. * @param string $domain
  6. * @param int $port
  7. *
  8. * @return string
  9. */
  10. function gen_domain($domain, $port)
  11. {
  12. if ($port == 80 || !isset($port))
  13. {
  14. $url = $domain;
  15. }
  16. else
  17. {
  18. $url = $domain .":". $port;
  19. };
  20. return $url;
  21. }
  22. /**
  23. * Checks that $domain is a valid domain or ip.
  24. *
  25. * @param string $domain
  26. *
  27. * @return bool
  28. */
  29. function is_valid_domain($domain)
  30. {
  31. $domain_regex = "/^(xn--)?([\w0-9]([\w0-9\-]{0,61}[\w0-9])?\.)+(xn--)?[\w]{2,6}$/i";
  32. return (filter_var($domain, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) != false || preg_match($domain_regex, $domain));
  33. }
  34. /**
  35. * Converts Internationalized Domain Name (IDN) domain name to and from IDNA ASCII format
  36. *
  37. * @param string $domain
  38. *
  39. * @return string Converted domain name, either in ASCII format or UTF-8
  40. */
  41. /**
  42. * @return string
  43. */
  44. function convert_idn_domain($domain)
  45. {
  46. // Get domain length
  47. $domain_length = strlen($domain);
  48. // Perform two idn operations, convert to ascii and convert to utf8
  49. $idn_ascii_domain = idn_to_ascii($domain);
  50. // IDN utf8 domain detected, return converted domain.
  51. if ($domain_length != strlen($idn_ascii_domain))
  52. {
  53. return $idn_ascii_domain;
  54. }
  55. $idn_utf8_domain = idn_to_utf8($domain);
  56. // IDN ascii domain detected, return converted domain.
  57. if ($domain_length != strlen($idn_utf8_domain)) {
  58. return $idn_utf8_domain;
  59. }
  60. return $domain;
  61. }
  62. /**
  63. * Filters the given domain and split it into an array with a port number.
  64. *
  65. * @param string $domain
  66. *
  67. * @return array The domain and the port number.
  68. */
  69. function filter_domain($domain)
  70. {
  71. // Convet IDN domain to ascii (if required)
  72. $domain = convert_idn_domain($domain);
  73. $domain = preg_replace("/[^A-Za-z0-9-\/\.\:]/", "", $domain);
  74. // Split the variable into two, $domain & $port.
  75. $result = explode(":", $domain);
  76. // If the port is not numeric or not set we use port 80.
  77. if (!isset($result[1]) || !is_numeric($result[1]))
  78. {
  79. $result[1] = 80;
  80. }
  81. return $result;
  82. }
  83. /**
  84. * Gets the http status code from $domain, using $port.
  85. *
  86. * @param string $domain
  87. * @param int $port
  88. *
  89. * @return array
  90. */
  91. function get_response($domain, $port)
  92. {
  93. global $setting;
  94. if ( is_valid_domain($domain) )
  95. {
  96. // create a new cURL resource
  97. $ch = curl_init();
  98. // set URL and other appropriate options
  99. curl_setopt($ch, CURLOPT_URL, "http://" . $domain);
  100. curl_setopt($ch, CURLOPT_PORT, $port);
  101. curl_setopt($ch, CURLOPT_USERAGENT, "Is is up? (+https://isitup.org)");
  102. curl_setopt($ch, CURLOPT_TIMEOUT, $setting["timeout"]);
  103. // This changes the request method to HEAD
  104. curl_setopt($ch, CURLOPT_NOBODY, true);
  105. // grab URL and pass it to the browser
  106. curl_exec($ch);
  107. $data = array
  108. (
  109. "code" => curl_getinfo($ch, CURLINFO_HTTP_CODE),
  110. "time" => curl_getinfo($ch, CURLINFO_CONNECT_TIME),
  111. "valid" => true
  112. );
  113. // close cURL resource, and free up system resources
  114. curl_close($ch);
  115. }
  116. else
  117. {
  118. $data = array
  119. (
  120. "code" => null,
  121. "time" => 0,
  122. "valid" => false
  123. );
  124. }
  125. return $data;
  126. }
  127. /**
  128. * Generates an id from $code.
  129. *
  130. * @param int $code
  131. *
  132. * @return int
  133. */
  134. function gen_id($data)
  135. {
  136. $good_codes = array(200, 301, 302, 303, 304, 307, 308, 400, 401, 403, 405);
  137. if ($data["valid"] === false)
  138. {
  139. $id = 3;
  140. }
  141. else if (is_numeric($data["code"]) && in_array($data["code"], $good_codes))
  142. {
  143. $id = 1;
  144. }
  145. else
  146. {
  147. $id = 2;
  148. };
  149. return $id;
  150. }
  151. /**
  152. * Generates the page title.
  153. *
  154. * @param int $id
  155. * @param string $domain
  156. *
  157. * @return string
  158. */
  159. function gen_title($id, $domain)
  160. {
  161. switch ($id)
  162. {
  163. case 3:
  164. return "Woops...";
  165. case 1:
  166. return "Yay, " . $domain . " is up.";
  167. case 2:
  168. return "Oh no! " . $domain . " is down.";
  169. }
  170. }
  171. /**
  172. * Generates the html for display.
  173. *
  174. * @param int $id
  175. * @param string $domain
  176. * @param int $port
  177. * @param int $time
  178. * @param int $code
  179. *
  180. * @return string
  181. */
  182. function gen_html($id, $domain, $port, $time, $code)
  183. {
  184. $units = gen_units($time);
  185. if ( $time < 1 )
  186. {
  187. $time = $time * 1000;
  188. }
  189. else
  190. {
  191. $time = round($time, 2);
  192. }
  193. if ( $time <= 0 ) $time = "< 1";
  194. if ( $id == 1 )
  195. {
  196. $html = "<p><a href=\"http://" . gen_domain($domain, $port) . "\" class=\"domain\" title=\"http://" . $domain . "/\" rel=\"nofollow\">" . $domain . "</a> is up.</p>\n\n";
  197. $html .= "\t<p class=\"smaller\">It took " . $time . " " . $units . " for a " . gen_http_wiki_link($code) . " response code" . show_ip($domain) . ".</p>\n\n";
  198. $html .= "\t<p class=\"smaller\"><a href=\"/\" title=\"Home\">Go back</a> to check another site" . gen_save($domain) . ".</p>\n";
  199. }
  200. else if ( $id == 2 )
  201. {
  202. if (!empty($code) && is_numeric($code))
  203. {
  204. $text = "We got a " . gen_http_wiki_link($code) . " response code" . show_ip($domain) . ".";
  205. };
  206. $html = "<p><a href=\"http://" . gen_domain($domain, $port) . "\" class=\"domain\" title=\"http://" . $domain . "/\" rel=\"nofollow\">" . $domain . "</a> seems to be down!</p>\n\n";
  207. if ( isset($text) )
  208. {
  209. $html .= "\t<p class=\"smaller\">" . $text . "</p>\n";
  210. };
  211. $html .= "\t<p class=\"smaller\"><a href=\"/\" title=\"Home\">Go back</a> to check another site" . gen_save($domain) . ".</p>\n";
  212. }
  213. else if ( $id == 3 )
  214. {
  215. $html = "<p>We need a valid domain to check! <a href=\"/d/" . gen_domain($domain, $port) . "\">Try again.</a></p>\n";
  216. };
  217. if ($domain == "isitup.org" || $domain == "127.0.0.1")
  218. {
  219. $html = "<p>Have a think about what you've just done and <a href=\"/\" title=\"Better luck next time.\">try again.</a></p>\n";
  220. };
  221. return $html;
  222. }
  223. /**
  224. * Generates a link to wikipedia.
  225. *
  226. * @param int $code
  227. *
  228. * @return string
  229. */
  230. function gen_http_wiki_link($code)
  231. {
  232. switch ($code)
  233. {
  234. case ($code >= 500):
  235. $anchor = "5xx_Server_Error";
  236. break;
  237. case ($code >= 400):
  238. $anchor = "4xx_Client_Error";
  239. break;
  240. case ($code >= 300):
  241. $anchor = "3xx_Redirection";
  242. break;
  243. case ($code >= 200):
  244. $anchor = "2xx_Success";
  245. break;
  246. case ($code >= 100):
  247. $anchor = "1xx_Informational";
  248. break;
  249. }
  250. return "<a href=\"http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#" . $anchor . "\" title=\"Wikipedia - HTTP Status Codes\">" . $code . "</a>";
  251. }
  252. /**
  253. * Generates the units for the response time.
  254. *
  255. * @param int $time
  256. *
  257. * @return string
  258. */
  259. function gen_units($time)
  260. {
  261. switch ($time)
  262. {
  263. case 1:
  264. return "second";
  265. case ($time > 1):
  266. return "seconds";
  267. default:
  268. $units = "<a title=\"Milliseconds\" href=\"http://www.wolframalpha.com/input/?i=" . $time * 1000 . "%20milliseconds\">ms</a>";
  269. break;
  270. }
  271. return $units;
  272. }
  273. /**
  274. * Generates the save link.
  275. *
  276. * @param string $domain
  277. * @param array $default
  278. *
  279. * @return bool|string
  280. */
  281. function gen_save($domain)
  282. {
  283. global $setting;
  284. $array = array();
  285. if ( isset($_COOKIE["input"]) )
  286. {
  287. $array[] = preg_replace("/[^A-Za-z0-9-\/\.\: ]/", "", trim($_COOKIE["input"]));
  288. };
  289. $array[] = $setting["default"];
  290. if ( !in_array($domain, $array) )
  291. {
  292. return " or <a href=\"/save/" . $domain . "\" title=\"Use " . $domain . " as the default site to check\">save</a> this as your default";
  293. };
  294. return false;
  295. }
  296. /**
  297. * Gets the ip address of the domain we're checking.
  298. *
  299. * @param string $domain
  300. *
  301. * @return string
  302. */
  303. function show_ip($domain)
  304. {
  305. $domexprcheck = "/^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/i";
  306. $ip = gethostbyname($domain);
  307. if (preg_match($domexprcheck, $domain) == true)
  308. {
  309. $text = " with an ip of <a href=\"http://" . $ip . "/\" title=\"http://" . $ip . "/\">" . $ip . "</a>";
  310. }
  311. else
  312. {
  313. $text = null;
  314. }
  315. return $text;
  316. }
  317. /**
  318. * Gets $cookie and turns it into an array
  319. *
  320. * @param string $cookie
  321. *
  322. * @return bool|array
  323. */
  324. function get_cookie($cookie)
  325. {
  326. if ( isset($_COOKIE[$cookie]) )
  327. {
  328. $clean = stripslashes(preg_replace("/[^A-Za-z0-9-\.\,\: ]/", "", trim($_COOKIE[$cookie])));
  329. return $clean;
  330. };
  331. return false;
  332. }
  333. /**
  334. * Sets a cookie.
  335. *
  336. * @param string $name
  337. */
  338. function set_cookie($name, $value)
  339. {
  340. setcookie($name, $value, time() + 60 * 60 * 24 * 365, "/", $_SERVER["SERVER_NAME"], 0, 1);
  341. }
  342. /**
  343. * Removes one or more cookies.
  344. *
  345. * @param array|string $cookie
  346. *
  347. * @return bool
  348. */
  349. function remove_cookies($cookie = array())
  350. {
  351. if ( is_array($cookie) )
  352. {
  353. foreach ($cookie as $value)
  354. {
  355. setcookie($value, false, time() - 60 * 60 * 24 * 365, "/", $_SERVER["SERVER_NAME"], 0, 1);
  356. };
  357. }
  358. else
  359. {
  360. setcookie($cookie, false, time() - 60 * 60 * 24 * 365, "/", $_SERVER["SERVER_NAME"], 0, 1);
  361. };
  362. return false;
  363. }
  364. /**
  365. * Gets the correct input value for the homepage.
  366. *
  367. * @param string $a the remote domain
  368. * @param array $b the default domain
  369. *
  370. * @return string
  371. */
  372. function get_domain($remote, $default)
  373. {
  374. $domain = $default;
  375. if (!isset($_GET["clear"]) && (!empty($_GET["d"]) || !empty($_COOKIE["input"])))
  376. {
  377. $domain = $remote;
  378. }
  379. return $domain;
  380. }
  381. /**
  382. * Gets the correct value for the input_val javascript variable on the homepage.
  383. *
  384. * @param string $a the remote domain
  385. * @param array $b the default domain
  386. *
  387. * @return string
  388. */
  389. function get_jsdomain($remote, $default)
  390. {
  391. if (isset($_GET["save"]) && isset($_GET["d"]))
  392. {
  393. $domain = $remote;
  394. }
  395. else if (isset($_GET["clear"]))
  396. {
  397. $domain = $default;
  398. }
  399. else if (!empty($_COOKIE["input"]) && empty($_GET["d"]))
  400. {
  401. $domain = $remote;
  402. }
  403. else if (isset($_GET["d"]) && !isset($_GET["save"]))
  404. {
  405. $domain = null;
  406. }
  407. else
  408. {
  409. $domain = $default;
  410. };
  411. return $domain;
  412. }
  413. /**
  414. * Tests if a clear link should be shown or not.
  415. *
  416. * @return bool
  417. */
  418. function show_clear()
  419. {
  420. if (isset($_COOKIE["input"])
  421. && !isset($_GET["clear"])
  422. || isset($_GET["save"])
  423. && isset($_GET["d"])
  424. || isset($_COOKIE["domains"])
  425. && !isset($_GET["clear"]))
  426. {
  427. return true;
  428. }
  429. return false;
  430. }
  431. /**
  432. * Generates the output for the api request.
  433. *
  434. * @param array $data
  435. * @param string $output The requested output type.
  436. *
  437. * @return string The api result.
  438. */
  439. function gen_api($data, $output)
  440. {
  441. switch ($output)
  442. {
  443. case "txt":
  444. return gen_txt($data);
  445. case "json":
  446. return gen_json($data);
  447. default:
  448. return false;
  449. }
  450. }
  451. /**
  452. * Generates the json output for an api request.
  453. *
  454. * @param array $data
  455. *
  456. * @return string The api result as json.
  457. */
  458. function gen_json($data)
  459. {
  460. // Allow the use of this json on any domain.
  461. header('Access-Control-Allow-Origin: *');
  462. $data = tidy_array($data, null);
  463. $json = format_json(json_encode($data, JSON_UNESCAPED_UNICODE));
  464. // JSONP callback function
  465. if ( isset($_GET["callback"]) )
  466. {
  467. header('Content-Type: application/javascript; charset=utf-8');
  468. $json = safe_callback($_GET["callback"]) . "(" . $json . ");";
  469. }
  470. else
  471. {
  472. header('Content-Type: application/json; charset=utf-8');
  473. }
  474. return $json;
  475. }
  476. /**
  477. * Generates the text output for an api request.
  478. *
  479. * @param array $data
  480. *
  481. * @return string The api result as csv.
  482. */
  483. function gen_txt($data)
  484. {
  485. header('Content-Type: text/plain');
  486. $data = tidy_array($data, "NULL");
  487. $txt = "";
  488. $last_key = end(array_keys($data));
  489. foreach ($data as $key => $value)
  490. {
  491. $txt = $txt . $value;
  492. if ($key != $last_key) $txt = $txt . ", ";
  493. }
  494. return $txt;
  495. }
  496. /**
  497. * Replaces empty values from an array with a given value.
  498. *
  499. * @param array $array
  500. * @param char $replacement_value
  501. *
  502. * @return array The cleaned array.
  503. */
  504. function tidy_array($array, $replacement_value)
  505. {
  506. foreach ($array as &$value)
  507. {
  508. if ( empty($value) ) $value = $replacement_value;
  509. };
  510. unset($value);
  511. return $array;
  512. }
  513. /**
  514. * Formats the JSON response, adding whitespace for readability.
  515. *
  516. * @param string $json
  517. *
  518. * @return string The formatted JSON.
  519. */
  520. function format_json($json)
  521. {
  522. $pattern = array(',"', '{', '}', ':');
  523. $replacement = array(",\n \"", "{\n ", "\n}", ': ');
  524. $formatted_json = str_replace($pattern, $replacement, $json);
  525. return $formatted_json;
  526. }
  527. /**
  528. * Ensures the callback cannot be used for ~bad things~.
  529. *
  530. * @param string $input
  531. *
  532. * @return string The safe callback method.
  533. */
  534. function safe_callback($input)
  535. {
  536. $output = strip_tags($input);
  537. $chars = array(";", "(", ")", "\"", "\'");
  538. $output = str_replace($chars, "", $output);
  539. return $output;
  540. }