PageRenderTime 43ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/system/core/Input.php

https://github.com/chriskelley/CodeIgniter
PHP | 899 lines | 459 code | 113 blank | 327 comment | 71 complexity | 1ac18662c942c3480dad69e14ade866e MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. <?php
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 5.2.4 or newer
  6. *
  7. * NOTICE OF LICENSE
  8. *
  9. * Licensed under the Open Software License version 3.0
  10. *
  11. * This source file is subject to the Open Software License (OSL 3.0) that is
  12. * bundled with this package in the files license.txt / license.rst. It is
  13. * also available through the world wide web at this URL:
  14. * http://opensource.org/licenses/OSL-3.0
  15. * If you did not receive a copy of the license and are unable to obtain it
  16. * through the world wide web, please send an email to
  17. * licensing@ellislab.com so we can send you a copy immediately.
  18. *
  19. * @package CodeIgniter
  20. * @author EllisLab Dev Team
  21. * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
  22. * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  23. * @link http://codeigniter.com
  24. * @since Version 1.0
  25. * @filesource
  26. */
  27. defined('BASEPATH') OR exit('No direct script access allowed');
  28. /**
  29. * Input Class
  30. *
  31. * Pre-processes global input data for security
  32. *
  33. * @package CodeIgniter
  34. * @subpackage Libraries
  35. * @category Input
  36. * @author EllisLab Dev Team
  37. * @link http://codeigniter.com/user_guide/libraries/input.html
  38. */
  39. class CI_Input {
  40. /**
  41. * IP address of the current user
  42. *
  43. * @var string
  44. */
  45. public $ip_address = FALSE;
  46. /**
  47. * User agent strin
  48. *
  49. * @var string
  50. */
  51. public $user_agent = FALSE;
  52. /**
  53. * Allow GET array flag
  54. *
  55. * If set to FALSE, then $_GET will be set to an empty array.
  56. *
  57. * @var bool
  58. */
  59. protected $_allow_get_array = TRUE;
  60. /**
  61. * Standartize new lines flag
  62. *
  63. * If set to TRUE, then newlines are standardized.
  64. *
  65. * @var bool
  66. */
  67. protected $_standardize_newlines = TRUE;
  68. /**
  69. * Enable XSS flag
  70. *
  71. * Determines whether the XSS filter is always active when
  72. * GET, POST or COOKIE data is encountered.
  73. * Set automatically based on config setting.
  74. *
  75. * @var bool
  76. */
  77. protected $_enable_xss = FALSE;
  78. /**
  79. * Enable CSRF flag
  80. *
  81. * Enables a CSRF cookie token to be set.
  82. * Set automatically based on config setting.
  83. *
  84. * @var bool
  85. */
  86. protected $_enable_csrf = FALSE;
  87. /**
  88. * List of all HTTP request headers
  89. *
  90. * @var array
  91. */
  92. protected $headers = array();
  93. /**
  94. * Input stream data
  95. *
  96. * Parsed from php://input at runtime
  97. *
  98. * @see CI_Input::input_stream()
  99. * @var array
  100. */
  101. protected $_input_stream = NULL;
  102. /**
  103. * Class constructor
  104. *
  105. * Determines whether to globally enable the XSS processing
  106. * and whether to allow the $_GET array.
  107. *
  108. * @return void
  109. */
  110. public function __construct()
  111. {
  112. log_message('debug', 'Input Class Initialized');
  113. $this->_allow_get_array = (config_item('allow_get_array') === TRUE);
  114. $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
  115. $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
  116. global $SEC;
  117. $this->security =& $SEC;
  118. // Do we need the UTF-8 class?
  119. if (UTF8_ENABLED === TRUE)
  120. {
  121. global $UNI;
  122. $this->uni =& $UNI;
  123. }
  124. // Sanitize global arrays
  125. $this->_sanitize_globals();
  126. }
  127. // --------------------------------------------------------------------
  128. /**
  129. * Fetch from array
  130. *
  131. * Internal method used to retrieve values from global arrays.
  132. *
  133. * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc.
  134. * @param string $index Index for item to be fetched from $array
  135. * @param bool $xss_clean Whether to apply XSS filtering
  136. * @return mixed
  137. */
  138. protected function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
  139. {
  140. if (isset($array[$index]))
  141. {
  142. $value = $array[$index];
  143. }
  144. elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation
  145. {
  146. $value = $array;
  147. for ($i = 0; $i < $count; $i++)
  148. {
  149. $key = trim($matches[0][$i], '[]');
  150. if ($key === '') // Empty notation will return the value as array
  151. {
  152. break;
  153. }
  154. if (isset($value[$key]))
  155. {
  156. $value = $value[$key];
  157. }
  158. else
  159. {
  160. return NULL;
  161. }
  162. }
  163. }
  164. else
  165. {
  166. return NULL;
  167. }
  168. return ($xss_clean === TRUE)
  169. ? $this->security->xss_clean($value)
  170. : $value;
  171. }
  172. // --------------------------------------------------------------------
  173. /**
  174. * Fetch an item from the GET array
  175. *
  176. * @param string $index Index for item to be fetched from $_GET
  177. * @param bool $xss_clean Whether to apply XSS filtering
  178. * @return mixed
  179. */
  180. public function get($index = NULL, $xss_clean = FALSE)
  181. {
  182. // Check if a field has been provided
  183. if ($index === NULL)
  184. {
  185. if (empty($_GET))
  186. {
  187. return array();
  188. }
  189. $get = array();
  190. // loop through the full _GET array
  191. foreach (array_keys($_GET) as $key)
  192. {
  193. $get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean);
  194. }
  195. return $get;
  196. }
  197. return $this->_fetch_from_array($_GET, $index, $xss_clean);
  198. }
  199. // --------------------------------------------------------------------
  200. /**
  201. * Fetch an item from the POST array
  202. *
  203. * @param string $index Index for item to be fetched from $_POST
  204. * @param bool $xss_clean Whether to apply XSS filtering
  205. * @return mixed
  206. */
  207. public function post($index = NULL, $xss_clean = FALSE)
  208. {
  209. // Check if a field has been provided
  210. if ($index === NULL)
  211. {
  212. if (empty($_POST))
  213. {
  214. return array();
  215. }
  216. $post = array();
  217. // Loop through the full _POST array and return it
  218. foreach (array_keys($_POST) as $key)
  219. {
  220. $post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);
  221. }
  222. return $post;
  223. }
  224. return $this->_fetch_from_array($_POST, $index, $xss_clean);
  225. }
  226. // --------------------------------------------------------------------
  227. /**
  228. * Fetch an item from POST data with fallback to GET
  229. *
  230. * @param string $index Index for item to be fetched from $_POST or $_GET
  231. * @param bool $xss_clean Whether to apply XSS filtering
  232. * @return mixed
  233. */
  234. public function get_post($index = '', $xss_clean = FALSE)
  235. {
  236. return isset($_POST[$index])
  237. ? $this->post($index, $xss_clean)
  238. : $this->get($index, $xss_clean);
  239. }
  240. // --------------------------------------------------------------------
  241. /**
  242. * Fetch an item from the COOKIE array
  243. *
  244. * @param string $index Index for item to be fetched from $_COOKIE
  245. * @param bool $xss_clean Whether to apply XSS filtering
  246. * @return mixed
  247. */
  248. public function cookie($index = '', $xss_clean = FALSE)
  249. {
  250. return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
  251. }
  252. // --------------------------------------------------------------------
  253. /**
  254. * Fetch an item from the SERVER array
  255. *
  256. * @param string $index Index for item to be fetched from $_SERVER
  257. * @param bool $xss_clean Whether to apply XSS filtering
  258. * @return mixed
  259. */
  260. public function server($index = '', $xss_clean = FALSE)
  261. {
  262. return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
  263. }
  264. // ------------------------------------------------------------------------
  265. /**
  266. * Fetch an item from the php://input stream
  267. *
  268. * Useful when you need to access PUT, DELETE or PATCH request data.
  269. *
  270. * @param string $index Index for item to be fetched
  271. * @param bool $xss_clean Whether to apply XSS filtering
  272. * @return mixed
  273. */
  274. public function input_stream($index = '', $xss_clean = FALSE)
  275. {
  276. // The input stream can only be read once, so we'll need to check
  277. // if we have already done that first.
  278. if (is_array($this->_input_stream))
  279. {
  280. return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
  281. }
  282. // Parse the input stream in our cache var
  283. parse_str(file_get_contents('php://input'), $this->_input_stream);
  284. if ( ! is_array($this->_input_stream))
  285. {
  286. $this->_input_stream = array();
  287. return NULL;
  288. }
  289. return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
  290. }
  291. // ------------------------------------------------------------------------
  292. /**
  293. * Set cookie
  294. *
  295. * Accepts an arbitrary number of parameters (up to 7) or an associative
  296. * array in the first parameter containing all the values.
  297. *
  298. * @param string|mixed[] $name Cookie name or an array containing parameters
  299. * @param string $value Cookie value
  300. * @param int $expire Cookie expiration time in seconds
  301. * @param string $domain Cookie domain (e.g.: '.yourdomain.com')
  302. * @param string $path Cookie path (default: '/')
  303. * @param string $prefix Cookie name prefix
  304. * @param bool $secure Whether to only transfer cookies via SSL
  305. * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript)
  306. * @return void
  307. */
  308. public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
  309. {
  310. if (is_array($name))
  311. {
  312. // always leave 'name' in last place, as the loop will break otherwise, due to $$item
  313. foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item)
  314. {
  315. if (isset($name[$item]))
  316. {
  317. $$item = $name[$item];
  318. }
  319. }
  320. }
  321. if ($prefix === '' && config_item('cookie_prefix') !== '')
  322. {
  323. $prefix = config_item('cookie_prefix');
  324. }
  325. if ($domain == '' && config_item('cookie_domain') != '')
  326. {
  327. $domain = config_item('cookie_domain');
  328. }
  329. if ($path === '/' && config_item('cookie_path') !== '/')
  330. {
  331. $path = config_item('cookie_path');
  332. }
  333. if ($secure === FALSE && config_item('cookie_secure') !== FALSE)
  334. {
  335. $secure = config_item('cookie_secure');
  336. }
  337. if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE)
  338. {
  339. $httponly = config_item('cookie_httponly');
  340. }
  341. if ( ! is_numeric($expire))
  342. {
  343. $expire = time() - 86500;
  344. }
  345. else
  346. {
  347. $expire = ($expire > 0) ? time() + $expire : 0;
  348. }
  349. setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly);
  350. }
  351. // --------------------------------------------------------------------
  352. /**
  353. * Fetch the IP Address
  354. *
  355. * Determines and validates the visitor's IP address.
  356. *
  357. * @return string IP address
  358. */
  359. public function ip_address()
  360. {
  361. if ($this->ip_address !== FALSE)
  362. {
  363. return $this->ip_address;
  364. }
  365. $proxy_ips = config_item('proxy_ips');
  366. if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
  367. {
  368. $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
  369. }
  370. $this->ip_address = $this->server('REMOTE_ADDR');
  371. if ($proxy_ips)
  372. {
  373. foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header)
  374. {
  375. if (($spoof = $this->server($header)) !== NULL)
  376. {
  377. // Some proxies typically list the whole chain of IP
  378. // addresses through which the client has reached us.
  379. // e.g. client_ip, proxy_ip1, proxy_ip2, etc.
  380. sscanf($spoof, '%[^,]', $spoof);
  381. if ( ! $this->valid_ip($spoof))
  382. {
  383. $spoof = NULL;
  384. }
  385. else
  386. {
  387. break;
  388. }
  389. }
  390. }
  391. if ($spoof)
  392. {
  393. for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
  394. {
  395. // Check if we have an IP address or a subnet
  396. if (strpos($proxy_ips[$i], '/') === FALSE)
  397. {
  398. // An IP address (and not a subnet) is specified.
  399. // We can compare right away.
  400. if ($proxy_ips[$i] === $this->ip_address)
  401. {
  402. $this->ip_address = $spoof;
  403. break;
  404. }
  405. continue;
  406. }
  407. // We have a subnet ... now the heavy lifting begins
  408. isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
  409. // If the proxy entry doesn't match the IP protocol - skip it
  410. if (strpos($proxy_ips[$i], $separator) === FALSE)
  411. {
  412. continue;
  413. }
  414. // Convert the REMOTE_ADDR IP address to binary, if needed
  415. if ( ! isset($ip, $sprintf))
  416. {
  417. if ($separator === ':')
  418. {
  419. // Make sure we're have the "full" IPv6 format
  420. $ip = explode(':',
  421. str_replace('::',
  422. str_repeat(':', 9 - substr_count($this->ip_address, ':')),
  423. $this->ip_address
  424. )
  425. );
  426. for ($i = 0; $i < 8; $i++)
  427. {
  428. $ip[$i] = intval($ip[$i], 16);
  429. }
  430. $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
  431. }
  432. else
  433. {
  434. $ip = explode('.', $this->ip_address);
  435. $sprintf = '%08b%08b%08b%08b';
  436. }
  437. $ip = vsprintf($sprintf, $ip);
  438. }
  439. // Split the netmask length off the network address
  440. sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen);
  441. // Again, an IPv6 address is most likely in a compressed form
  442. if ($separator === ':')
  443. {
  444. $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
  445. for ($i = 0; $i < 8; $i++)
  446. {
  447. $netaddr[$i] = intval($netaddr[$i], 16);
  448. }
  449. }
  450. else
  451. {
  452. $netaddr = explode('.', $netaddr);
  453. }
  454. // Convert to binary and finally compare
  455. if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0)
  456. {
  457. $this->ip_address = $spoof;
  458. break;
  459. }
  460. }
  461. }
  462. }
  463. if ( ! $this->valid_ip($this->ip_address))
  464. {
  465. return $this->ip_address = '0.0.0.0';
  466. }
  467. return $this->ip_address;
  468. }
  469. // --------------------------------------------------------------------
  470. /**
  471. * Validate IP Address
  472. *
  473. * @param string $ip IP address
  474. * @param string $which IP protocol: 'ipv4' or 'ipv6'
  475. * @return bool
  476. */
  477. public function valid_ip($ip, $which = '')
  478. {
  479. switch (strtolower($which))
  480. {
  481. case 'ipv4':
  482. $which = FILTER_FLAG_IPV4;
  483. break;
  484. case 'ipv6':
  485. $which = FILTER_FLAG_IPV6;
  486. break;
  487. default:
  488. $which = NULL;
  489. break;
  490. }
  491. return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which);
  492. }
  493. // --------------------------------------------------------------------
  494. /**
  495. * Fetch User Agent string
  496. *
  497. * @return string|null User Agent string or NULL if it doesn't exist
  498. */
  499. public function user_agent()
  500. {
  501. if ($this->user_agent !== FALSE)
  502. {
  503. return $this->user_agent;
  504. }
  505. return $this->user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : NULL;
  506. }
  507. // --------------------------------------------------------------------
  508. /**
  509. * Sanitize Globals
  510. *
  511. * Internal method serving for the following purposes:
  512. *
  513. * - Unsets $_GET data (if query strings are not enabled)
  514. * - Unsets all globals if register_globals is enabled
  515. * - Cleans POST, COOKIE and SERVER data
  516. * - Standardizes newline characters to PHP_EOL
  517. *
  518. * @return void
  519. */
  520. protected function _sanitize_globals()
  521. {
  522. // It would be "wrong" to unset any of these GLOBALS.
  523. $protected = array(
  524. '_SERVER',
  525. '_GET',
  526. '_POST',
  527. '_FILES',
  528. '_REQUEST',
  529. '_SESSION',
  530. '_ENV',
  531. 'GLOBALS',
  532. 'HTTP_RAW_POST_DATA',
  533. 'system_folder',
  534. 'application_folder',
  535. 'BM',
  536. 'EXT',
  537. 'CFG',
  538. 'URI',
  539. 'RTR',
  540. 'OUT',
  541. 'IN'
  542. );
  543. // Unset globals for security.
  544. // This is effectively the same as register_globals = off
  545. // PHP 5.4 no longer has the register_globals functionality.
  546. if ( ! is_php('5.4'))
  547. {
  548. foreach (array($_GET, $_POST, $_COOKIE) as $global)
  549. {
  550. if (is_array($global))
  551. {
  552. foreach ($global as $key => $val)
  553. {
  554. if ( ! in_array($key, $protected))
  555. {
  556. global $$key;
  557. $$key = NULL;
  558. }
  559. }
  560. }
  561. elseif ( ! in_array($global, $protected))
  562. {
  563. global $$global;
  564. $$global = NULL;
  565. }
  566. }
  567. }
  568. // Is $_GET data allowed? If not we'll set the $_GET to an empty array
  569. if ($this->_allow_get_array === FALSE)
  570. {
  571. $_GET = array();
  572. }
  573. elseif (is_array($_GET) && count($_GET) > 0)
  574. {
  575. foreach ($_GET as $key => $val)
  576. {
  577. $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
  578. }
  579. }
  580. // Clean $_POST Data
  581. if (is_array($_POST) && count($_POST) > 0)
  582. {
  583. foreach ($_POST as $key => $val)
  584. {
  585. $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
  586. }
  587. }
  588. // Clean $_COOKIE Data
  589. if (is_array($_COOKIE) && count($_COOKIE) > 0)
  590. {
  591. // Also get rid of specially treated cookies that might be set by a server
  592. // or silly application, that are of no use to a CI application anyway
  593. // but that when present will trip our 'Disallowed Key Characters' alarm
  594. // http://www.ietf.org/rfc/rfc2109.txt
  595. // note that the key names below are single quoted strings, and are not PHP variables
  596. unset($_COOKIE['$Version']);
  597. unset($_COOKIE['$Path']);
  598. unset($_COOKIE['$Domain']);
  599. foreach ($_COOKIE as $key => $val)
  600. {
  601. $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
  602. }
  603. }
  604. // Sanitize PHP_SELF
  605. $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
  606. // CSRF Protection check
  607. if ($this->_enable_csrf === TRUE && ! $this->is_cli_request())
  608. {
  609. $this->security->csrf_verify();
  610. }
  611. log_message('debug', 'Global POST and COOKIE data sanitized');
  612. }
  613. // --------------------------------------------------------------------
  614. /**
  615. * Clean Input Data
  616. *
  617. * Internal method that aids in escaping data and
  618. * standardizing newline characters to PHP_EOL.
  619. *
  620. * @param string|string[] $str Input string(s)
  621. * @return string
  622. */
  623. protected function _clean_input_data($str)
  624. {
  625. if (is_array($str))
  626. {
  627. $new_array = array();
  628. foreach (array_keys($str) as $key)
  629. {
  630. $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]);
  631. }
  632. return $new_array;
  633. }
  634. /* We strip slashes if magic quotes is on to keep things consistent
  635. NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and
  636. it will probably not exist in future versions at all.
  637. */
  638. if ( ! is_php('5.4') && get_magic_quotes_gpc())
  639. {
  640. $str = stripslashes($str);
  641. }
  642. // Clean UTF-8 if supported
  643. if (UTF8_ENABLED === TRUE)
  644. {
  645. $str = $this->uni->clean_string($str);
  646. }
  647. // Remove control characters
  648. $str = remove_invisible_characters($str);
  649. // Should we filter the input data?
  650. if ($this->_enable_xss === TRUE)
  651. {
  652. $str = $this->security->xss_clean($str);
  653. }
  654. // Standardize newlines if needed
  655. if ($this->_standardize_newlines === TRUE)
  656. {
  657. return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str);
  658. }
  659. return $str;
  660. }
  661. // --------------------------------------------------------------------
  662. /**
  663. * Clean Keys
  664. *
  665. * Internal method that helps to prevent malicious users
  666. * from trying to exploit keys we make sure that keys are
  667. * only named with alpha-numeric text and a few other items.
  668. *
  669. * @param string $str Input string
  670. * @return string
  671. */
  672. protected function _clean_input_keys($str)
  673. {
  674. if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
  675. {
  676. set_status_header(503);
  677. echo 'Disallowed Key Characters.';
  678. exit(EXIT_USER_INPUT);
  679. }
  680. // Clean UTF-8 if supported
  681. if (UTF8_ENABLED === TRUE)
  682. {
  683. return $this->uni->clean_string($str);
  684. }
  685. return $str;
  686. }
  687. // --------------------------------------------------------------------
  688. /**
  689. * Request Headers
  690. *
  691. * @param bool $xss_clean Whether to apply XSS filtering
  692. * @return array
  693. */
  694. public function request_headers($xss_clean = FALSE)
  695. {
  696. // If header is already defined, return it immediately
  697. if ( ! empty($this->headers))
  698. {
  699. return $this->headers;
  700. }
  701. // In Apache, you can simply call apache_request_headers()
  702. if (function_exists('apache_request_headers'))
  703. {
  704. return $this->headers = apache_request_headers();
  705. }
  706. $this->headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
  707. foreach ($_SERVER as $key => $val)
  708. {
  709. if (sscanf($key, 'HTTP_%s', $header) === 1)
  710. {
  711. // take SOME_HEADER and turn it into Some-Header
  712. $header = str_replace('_', ' ', strtolower($header));
  713. $header = str_replace(' ', '-', ucwords($header));
  714. $this->headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
  715. }
  716. }
  717. return $this->headers;
  718. }
  719. // --------------------------------------------------------------------
  720. /**
  721. * Get Request Header
  722. *
  723. * Returns the value of a single member of the headers class member
  724. *
  725. * @param string $index Header name
  726. * @param bool $xss_clean Whether to apply XSS filtering
  727. * @return string|bool The requested header on success or FALSE on failure
  728. */
  729. public function get_request_header($index, $xss_clean = FALSE)
  730. {
  731. if (empty($this->headers))
  732. {
  733. $this->request_headers();
  734. }
  735. if ( ! isset($this->headers[$index]))
  736. {
  737. return NULL;
  738. }
  739. return ($xss_clean === TRUE)
  740. ? $this->security->xss_clean($this->headers[$index])
  741. : $this->headers[$index];
  742. }
  743. // --------------------------------------------------------------------
  744. /**
  745. * Is AJAX request?
  746. *
  747. * Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
  748. *
  749. * @return bool
  750. */
  751. public function is_ajax_request()
  752. {
  753. return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
  754. }
  755. // --------------------------------------------------------------------
  756. /**
  757. * Is CLI request?
  758. *
  759. * Test to see if a request was made from the command line.
  760. *
  761. * @return bool
  762. */
  763. public function is_cli_request()
  764. {
  765. return (php_sapi_name() === 'cli' OR defined('STDIN'));
  766. }
  767. // --------------------------------------------------------------------
  768. /**
  769. * Get Request Method
  770. *
  771. * Return the request method
  772. *
  773. * @param bool $upper Whether to return in upper or lower case
  774. * (default: FALSE)
  775. * @return string
  776. */
  777. public function method($upper = FALSE)
  778. {
  779. return ($upper)
  780. ? strtoupper($this->server('REQUEST_METHOD'))
  781. : strtolower($this->server('REQUEST_METHOD'));
  782. }
  783. }
  784. /* End of file Input.php */
  785. /* Location: ./system/core/Input.php */