blob: 3024fca785e6a53ff7437983578923c5618b84be [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreev64e98aa2012-01-07 20:29:10 +02008 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02009 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
Andrey Andreev64e98aa2012-01-07 20:29:10 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreevfe9309d2015-01-09 17:48:58 +020032 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
34 * @link http://codeigniter.com
35 * @since Version 1.0.0
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
41 * Input Class
42 *
43 * Pre-processes global input data for security
44 *
45 * @package CodeIgniter
46 * @subpackage Libraries
47 * @category Input
Derek Jonesf4a4bd82011-10-20 12:18:42 -050048 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000049 * @link http://codeigniter.com/user_guide/libraries/input.html
50 */
51class CI_Input {
Derek Allard2067d1a2008-11-13 22:59:24 +000052
David Behler9b5df592011-08-14 21:04:17 +020053 /**
54 * IP address of the current user
55 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030056 * @var string
David Behler9b5df592011-08-14 21:04:17 +020057 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030058 public $ip_address = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030059
David Behler9b5df592011-08-14 21:04:17 +020060 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +030061 * Allow GET array flag
David Behler9b5df592011-08-14 21:04:17 +020062 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030063 * If set to FALSE, then $_GET will be set to an empty array.
David Behler9b5df592011-08-14 21:04:17 +020064 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030065 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020066 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030067 protected $_allow_get_array = TRUE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030068
David Behler9b5df592011-08-14 21:04:17 +020069 /**
Andrey Andreevbfb635b2014-01-08 18:32:05 +020070 * Standardize new lines flag
David Behler9b5df592011-08-14 21:04:17 +020071 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030072 * If set to TRUE, then newlines are standardized.
73 *
74 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020075 */
Andrey Andreevefc08e92014-04-15 14:32:52 +030076 protected $_standardize_newlines;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030077
David Behler9b5df592011-08-14 21:04:17 +020078 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +030079 * Enable XSS flag
80 *
81 * Determines whether the XSS filter is always active when
82 * GET, POST or COOKIE data is encountered.
83 * Set automatically based on config setting.
84 *
85 * @var bool
86 */
87 protected $_enable_xss = FALSE;
88
89 /**
90 * Enable CSRF flag
91 *
David Behler9b5df592011-08-14 21:04:17 +020092 * Enables a CSRF cookie token to be set.
Andrey Andreev1887ec62012-10-27 16:22:07 +030093 * Set automatically based on config setting.
David Behler9b5df592011-08-14 21:04:17 +020094 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030095 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020096 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030097 protected $_enable_csrf = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030098
David Behler9b5df592011-08-14 21:04:17 +020099 /**
100 * List of all HTTP request headers
101 *
102 * @var array
103 */
Andrey Andreev1887ec62012-10-27 16:22:07 +0300104 protected $headers = array();
David Behler9b5df592011-08-14 21:04:17 +0200105
Derek Allard2067d1a2008-11-13 22:59:24 +0000106 /**
Ignasimgf9fbf112015-02-06 09:21:07 +0100107 * Raw input stream data
108 *
109 * @see CI_Input::input_stream()
110 * @var array
111 */
112 protected $_raw_input_stream = NULL;
113
114 /**
Andrey Andreev303eef02012-11-06 14:55:48 +0200115 * Input stream data
116 *
117 * Parsed from php://input at runtime
118 *
119 * @see CI_Input::input_stream()
120 * @var array
121 */
Ignasimgf9fbf112015-02-06 09:21:07 +0100122 protected $_input_stream = NULL; // Kept for backward compatible.
Andrey Andreev303eef02012-11-06 14:55:48 +0200123
124 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300125 * Class constructor
Greg Akera9263282010-11-10 15:26:43 -0600126 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300127 * Determines whether to globally enable the XSS processing
128 * and whether to allow the $_GET array.
Andrey Andreev92ebfb62012-05-17 12:49:24 +0300129 *
130 * @return void
Greg Akera9263282010-11-10 15:26:43 -0600131 */
132 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 {
Andrey Andreevbfb635b2014-01-08 18:32:05 +0200134 $this->_allow_get_array = (config_item('allow_get_array') === TRUE);
135 $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
136 $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
fabianozenatti523cda32014-03-21 12:13:03 +0100137 $this->_standardize_newlines = (bool) config_item('standardize_newlines');
Derek Jones69fc4fc2010-03-02 13:36:31 -0600138
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200139 $this->security =& load_class('Security', 'core');
Derek Jones69fc4fc2010-03-02 13:36:31 -0600140
Pascal Krieteaaec1e42011-01-20 00:01:21 -0500141 // Do we need the UTF-8 class?
Derek Jones69fc4fc2010-03-02 13:36:31 -0600142 if (UTF8_ENABLED === TRUE)
143 {
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200144 $this->uni =& load_class('Utf8', 'core');
Derek Jones69fc4fc2010-03-02 13:36:31 -0600145 }
146
147 // Sanitize global arrays
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 $this->_sanitize_globals();
Andrey Andreev90726b82015-01-20 12:39:22 +0200149
150 log_message('info', 'Input Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000151 }
152
153 // --------------------------------------------------------------------
154
155 /**
Greg Akera9263282010-11-10 15:26:43 -0600156 * Fetch from array
157 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300158 * Internal method used to retrieve values from global arrays.
Greg Akera9263282010-11-10 15:26:43 -0600159 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300160 * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc.
Ahmad Anbarff89a4e2014-12-02 17:26:30 +0200161 * @param mixed $index Index for item to be fetched from $array
Andrey Andreev1887ec62012-10-27 16:22:07 +0300162 * @param bool $xss_clean Whether to apply XSS filtering
163 * @return mixed
Greg Akera9263282010-11-10 15:26:43 -0600164 */
Andrey Andreev7c60b122014-02-08 18:47:19 +0200165 protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000166 {
Andrey Andreevef29f832014-12-02 18:03:47 +0200167 is_bool($xss_clean) OR $xss_clean = $this->_enable_xss;
168
Andrey Andreev7c60b122014-02-08 18:47:19 +0200169 // If $index is NULL, it means that the whole $array is requested
Andrey Andreevef29f832014-12-02 18:03:47 +0200170 isset($index) OR $index = array_keys($array);
171
172 // allow fetching multiple keys at once
173 if (is_array($index))
Andrey Andreev7c60b122014-02-08 18:47:19 +0200174 {
175 $output = array();
Andrey Andreev6b3bf4c2014-12-02 18:04:41 +0200176 foreach ($index as $key)
Andrey Andreev7c60b122014-02-08 18:47:19 +0200177 {
178 $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean);
179 }
180
181 return $output;
182 }
183
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530184 if (isset($array[$index]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 {
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530186 $value = $array[$index];
187 }
nisheeth-barthwal47ea5a82013-03-26 18:57:28 +0530188 elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530189 {
nisheeth-barthwal47ea5a82013-03-26 18:57:28 +0530190 $value = $array;
nisheeth-barthwal77236e02013-03-25 23:42:36 +0530191 for ($i = 0; $i < $count; $i++)
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530192 {
nisheeth-barthwal77236e02013-03-25 23:42:36 +0530193 $key = trim($matches[0][$i], '[]');
nisheeth-barthwal408cbb42013-03-26 19:06:40 +0530194 if ($key === '') // Empty notation will return the value as array
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530195 {
nisheeth-barthwal77236e02013-03-25 23:42:36 +0530196 break;
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530197 }
nisheeth-barthwal47ea5a82013-03-26 18:57:28 +0530198
199 if (isset($value[$key]))
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530200 {
nisheeth-barthwal47ea5a82013-03-26 18:57:28 +0530201 $value = $value[$key];
nisheeth-barthwal77236e02013-03-25 23:42:36 +0530202 }
203 else
204 {
205 return NULL;
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530206 }
207 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000208 }
nisheeth-barthwal77236e02013-03-25 23:42:36 +0530209 else
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 {
nisheeth-barthwal77236e02013-03-25 23:42:36 +0530211 return NULL;
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 }
213
nisheeth-barthwal77236e02013-03-25 23:42:36 +0530214 return ($xss_clean === TRUE)
215 ? $this->security->xss_clean($value)
216 : $value;
Derek Allard2067d1a2008-11-13 22:59:24 +0000217 }
218
219 // --------------------------------------------------------------------
220
221 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400222 * Fetch an item from the GET array
223 *
Ahmad Anbarff89a4e2014-12-02 17:26:30 +0200224 * @param mixed $index Index for item to be fetched from $_GET
Andrey Andreev1887ec62012-10-27 16:22:07 +0300225 * @param bool $xss_clean Whether to apply XSS filtering
226 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400227 */
Andrey Andreev80a16b12014-01-08 17:19:03 +0200228 public function get($index = NULL, $xss_clean = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000229 {
nisheeth-barthwala5bcfb12013-03-23 10:53:51 +0530230 return $this->_fetch_from_array($_GET, $index, $xss_clean);
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 }
232
233 // --------------------------------------------------------------------
234
235 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400236 * Fetch an item from the POST array
237 *
Ahmad Anbarff89a4e2014-12-02 17:26:30 +0200238 * @param mixed $index Index for item to be fetched from $_POST
Andrey Andreev1887ec62012-10-27 16:22:07 +0300239 * @param bool $xss_clean Whether to apply XSS filtering
240 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400241 */
Andrey Andreev80a16b12014-01-08 17:19:03 +0200242 public function post($index = NULL, $xss_clean = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000243 {
nisheeth-barthwala5bcfb12013-03-23 10:53:51 +0530244 return $this->_fetch_from_array($_POST, $index, $xss_clean);
Derek Allard2067d1a2008-11-13 22:59:24 +0000245 }
246
247 // --------------------------------------------------------------------
248
249 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300250 * Fetch an item from POST data with fallback to GET
Timothy Warren40403d22012-04-19 16:38:50 -0400251 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300252 * @param string $index Index for item to be fetched from $_POST or $_GET
253 * @param bool $xss_clean Whether to apply XSS filtering
254 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400255 */
Andrey Andreev7c60b122014-02-08 18:47:19 +0200256 public function post_get($index, $xss_clean = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200258 return isset($_POST[$index])
nisheeth-barthwala5bcfb12013-03-23 10:53:51 +0530259 ? $this->post($index, $xss_clean)
260 : $this->get($index, $xss_clean);
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 }
262
263 // --------------------------------------------------------------------
264
265 /**
vlakoff441fd262013-08-11 20:36:41 +0200266 * Fetch an item from GET data with fallback to POST
267 *
268 * @param string $index Index for item to be fetched from $_GET or $_POST
269 * @param bool $xss_clean Whether to apply XSS filtering
270 * @return mixed
271 */
Andrey Andreev7c60b122014-02-08 18:47:19 +0200272 public function get_post($index, $xss_clean = NULL)
vlakoff441fd262013-08-11 20:36:41 +0200273 {
274 return isset($_GET[$index])
275 ? $this->get($index, $xss_clean)
276 : $this->post($index, $xss_clean);
277 }
278
279 // --------------------------------------------------------------------
280
281 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400282 * Fetch an item from the COOKIE array
283 *
Ahmad Anbarff89a4e2014-12-02 17:26:30 +0200284 * @param mixed $index Index for item to be fetched from $_COOKIE
Andrey Andreev1887ec62012-10-27 16:22:07 +0300285 * @param bool $xss_clean Whether to apply XSS filtering
286 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400287 */
Andrey Andreev7c60b122014-02-08 18:47:19 +0200288 public function cookie($index = NULL, $xss_clean = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000289 {
nisheeth-barthwala5bcfb12013-03-23 10:53:51 +0530290 return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 }
292
Andrey Andreev1887ec62012-10-27 16:22:07 +0300293 // --------------------------------------------------------------------
294
295 /**
296 * Fetch an item from the SERVER array
297 *
Ahmad Anbarff89a4e2014-12-02 17:26:30 +0200298 * @param mixed $index Index for item to be fetched from $_SERVER
Andrey Andreev1887ec62012-10-27 16:22:07 +0300299 * @param bool $xss_clean Whether to apply XSS filtering
300 * @return mixed
301 */
Andrey Andreev7c60b122014-02-08 18:47:19 +0200302 public function server($index, $xss_clean = NULL)
Andrey Andreev1887ec62012-10-27 16:22:07 +0300303 {
304 return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
305 }
306
Derek Jones69fc4fc2010-03-02 13:36:31 -0600307 // ------------------------------------------------------------------------
308
309 /**
Ignasimgf9fbf112015-02-06 09:21:07 +0100310 * Fetch raw data from php://input stream
311 *
312 * Useful when data is not an array and might contain = and & symbols.
313 */
314 public function raw_input_stream()
315 {
316 // Prior to PHP 5.6, the input stream can only be read once,
317 // so we'll need to check if we have already done that first.
318 if (is_null($this->_raw_input_stream))
319 {
320 $this->_raw_input_stream = file_get_contents('php://input');
321 }
322
323 return $this->_raw_input_stream;
324 }
325
326 // ------------------------------------------------------------------------
327
328 /**
Andrey Andreev303eef02012-11-06 14:55:48 +0200329 * Fetch an item from the php://input stream
330 *
331 * Useful when you need to access PUT, DELETE or PATCH request data.
332 *
333 * @param string $index Index for item to be fetched
334 * @param bool $xss_clean Whether to apply XSS filtering
335 * @return mixed
336 */
Andrey Andreev7c60b122014-02-08 18:47:19 +0200337 public function input_stream($index = NULL, $xss_clean = NULL)
Andrey Andreev303eef02012-11-06 14:55:48 +0200338 {
Ignasimgf9fbf112015-02-06 09:21:07 +0100339 parse_str($this->raw_input_stream(), $this->_input_stream);
Andrey Andreev303eef02012-11-06 14:55:48 +0200340 return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
341 }
Ignasimgf9fbf112015-02-06 09:21:07 +0100342
343 // ------------------------------------------------------------------------
344
345 /**
346 * Fetch an item from the php://input stream
347 *
348 * Useful when you need to access input that's been send as raw json data'
349 *
350 * @param string $index Index for item to be fetched
351 * @param bool $xss_clean Whether to apply XSS filtering
352 * @return mixed
353 */
354 public function json_input_stream($index = NULL, $xss_clean = NULL)
355 {
356 $json_input_stream = json_decode($this->raw_input_stream(), true);
357 return $this->_fetch_from_array($json_input_stream, $index, $xss_clean);
358 }
Andrey Andreev303eef02012-11-06 14:55:48 +0200359
360 // ------------------------------------------------------------------------
361
362 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400363 * Set cookie
364 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300365 * Accepts an arbitrary number of parameters (up to 7) or an associative
Timothy Warren40403d22012-04-19 16:38:50 -0400366 * array in the first parameter containing all the values.
367 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300368 * @param string|mixed[] $name Cookie name or an array containing parameters
369 * @param string $value Cookie value
370 * @param int $expire Cookie expiration time in seconds
371 * @param string $domain Cookie domain (e.g.: '.yourdomain.com')
372 * @param string $path Cookie path (default: '/')
373 * @param string $prefix Cookie name prefix
374 * @param bool $secure Whether to only transfer cookies via SSL
375 * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript)
Timothy Warren40403d22012-04-19 16:38:50 -0400376 * @return void
377 */
Andrey Andreev8f5420b2014-01-06 10:34:23 +0200378 public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600379 {
380 if (is_array($name))
381 {
tobiasbg9aa7dc92011-02-18 21:57:13 +0100382 // always leave 'name' in last place, as the loop will break otherwise, due to $$item
freewil4ad0fd82012-03-13 22:37:42 -0400383 foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600384 {
385 if (isset($name[$item]))
386 {
387 $$item = $name[$item];
388 }
389 }
390 }
391
Alex Bilbieed944a32012-06-02 11:07:47 +0100392 if ($prefix === '' && config_item('cookie_prefix') !== '')
Derek Jones69fc4fc2010-03-02 13:36:31 -0600393 {
394 $prefix = config_item('cookie_prefix');
395 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300396
397 if ($domain == '' && config_item('cookie_domain') != '')
Derek Jones69fc4fc2010-03-02 13:36:31 -0600398 {
399 $domain = config_item('cookie_domain');
400 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300401
Alex Bilbieed944a32012-06-02 11:07:47 +0100402 if ($path === '/' && config_item('cookie_path') !== '/')
Derek Jones69fc4fc2010-03-02 13:36:31 -0600403 {
404 $path = config_item('cookie_path');
405 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300406
Andrey Andreevd444d442014-10-06 00:00:08 +0300407 if ($secure === FALSE && config_item('cookie_secure') === TRUE)
tobiasbg9aa7dc92011-02-18 21:57:13 +0100408 {
409 $secure = config_item('cookie_secure');
410 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300411
Alex Bilbieed944a32012-06-02 11:07:47 +0100412 if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE)
freewil4ad0fd82012-03-13 22:37:42 -0400413 {
414 $httponly = config_item('cookie_httponly');
415 }
Derek Jones69fc4fc2010-03-02 13:36:31 -0600416
417 if ( ! is_numeric($expire))
418 {
419 $expire = time() - 86500;
420 }
421 else
422 {
Phil Sturgeonc8089152010-12-27 19:06:28 +0000423 $expire = ($expire > 0) ? time() + $expire : 0;
Derek Jones69fc4fc2010-03-02 13:36:31 -0600424 }
425
freewil4ad0fd82012-03-13 22:37:42 -0400426 setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600427 }
428
Derek Allard2067d1a2008-11-13 22:59:24 +0000429 // --------------------------------------------------------------------
430
431 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400432 * Fetch the IP Address
433 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300434 * Determines and validates the visitor's IP address.
435 *
436 * @return string IP address
Timothy Warren40403d22012-04-19 16:38:50 -0400437 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800438 public function ip_address()
Derek Allard2067d1a2008-11-13 22:59:24 +0000439 {
440 if ($this->ip_address !== FALSE)
441 {
442 return $this->ip_address;
443 }
Barry Mienydd671972010-10-04 16:33:58 +0200444
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300445 $proxy_ips = config_item('proxy_ips');
Andrey Andreevea7a8662012-10-09 13:36:31 +0300446 if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300447 {
448 $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
449 }
Andrey Andreev5b92ae12012-10-04 13:05:03 +0300450
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300451 $this->ip_address = $this->server('REMOTE_ADDR');
452
453 if ($proxy_ips)
454 {
455 foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header)
Jordan Pittman8960acf2012-07-23 09:05:49 -0300456 {
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300457 if (($spoof = $this->server($header)) !== NULL)
Jordan Pittman8960acf2012-07-23 09:05:49 -0300458 {
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300459 // Some proxies typically list the whole chain of IP
460 // addresses through which the client has reached us.
461 // e.g. client_ip, proxy_ip1, proxy_ip2, etc.
Andrey Andreeve24eed72012-11-02 23:33:45 +0200462 sscanf($spoof, '%[^,]', $spoof);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300463
464 if ( ! $this->valid_ip($spoof))
465 {
466 $spoof = NULL;
467 }
468 else
469 {
Jordan Pittmana5a71352012-07-20 19:36:43 -0300470 break;
471 }
472 }
Andrey Andreev5b92ae12012-10-04 13:05:03 +0300473 }
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300474
Andrey Andreeve45ad2b2012-10-09 13:11:15 +0300475 if ($spoof)
Andrey Andreev5b92ae12012-10-04 13:05:03 +0300476 {
Andrey Andreev9df35b42012-10-09 13:37:58 +0300477 for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300478 {
479 // Check if we have an IP address or a subnet
480 if (strpos($proxy_ips[$i], '/') === FALSE)
481 {
482 // An IP address (and not a subnet) is specified.
483 // We can compare right away.
484 if ($proxy_ips[$i] === $this->ip_address)
485 {
486 $this->ip_address = $spoof;
487 break;
488 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000489
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300490 continue;
491 }
492
493 // We have a subnet ... now the heavy lifting begins
494 isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
495
496 // If the proxy entry doesn't match the IP protocol - skip it
497 if (strpos($proxy_ips[$i], $separator) === FALSE)
498 {
499 continue;
500 }
501
502 // Convert the REMOTE_ADDR IP address to binary, if needed
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300503 if ( ! isset($ip, $sprintf))
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300504 {
505 if ($separator === ':')
506 {
507 // Make sure we're have the "full" IPv6 format
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300508 $ip = explode(':',
509 str_replace('::',
510 str_repeat(':', 9 - substr_count($this->ip_address, ':')),
511 $this->ip_address
512 )
513 );
514
515 for ($i = 0; $i < 8; $i++)
516 {
517 $ip[$i] = intval($ip[$i], 16);
518 }
519
520 $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300521 }
522 else
523 {
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300524 $ip = explode('.', $this->ip_address);
525 $sprintf = '%08b%08b%08b%08b';
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300526 }
527
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300528 $ip = vsprintf($sprintf, $ip);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300529 }
530
531 // Split the netmask length off the network address
Andrey Andreeve24eed72012-11-02 23:33:45 +0200532 sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300533
534 // Again, an IPv6 address is most likely in a compressed form
535 if ($separator === ':')
536 {
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300537 $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
538 for ($i = 0; $i < 8; $i++)
539 {
540 $netaddr[$i] = intval($netaddr[$i], 16);
541 }
542 }
543 else
544 {
545 $netaddr = explode('.', $netaddr);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300546 }
547
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300548 // Convert to binary and finally compare
549 if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0)
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300550 {
551 $this->ip_address = $spoof;
552 break;
553 }
554 }
555 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000556 }
557
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 if ( ! $this->valid_ip($this->ip_address))
559 {
Andrey Andreev64e98aa2012-01-07 20:29:10 +0200560 return $this->ip_address = '0.0.0.0';
Derek Allard2067d1a2008-11-13 22:59:24 +0000561 }
562
563 return $this->ip_address;
564 }
565
566 // --------------------------------------------------------------------
567
568 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400569 * Validate IP Address
570 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300571 * @param string $ip IP address
572 * @param string $which IP protocol: 'ipv4' or 'ipv6'
Timothy Warren40403d22012-04-19 16:38:50 -0400573 * @return bool
574 */
Andrey Andreev5a257182012-06-10 06:18:14 +0300575 public function valid_ip($ip, $which = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000576 {
Andrey Andreev5a257182012-06-10 06:18:14 +0300577 switch (strtolower($which))
578 {
579 case 'ipv4':
580 $which = FILTER_FLAG_IPV4;
581 break;
582 case 'ipv6':
583 $which = FILTER_FLAG_IPV6;
584 break;
585 default:
586 $which = NULL;
587 break;
588 }
589
590 return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which);
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 }
592
593 // --------------------------------------------------------------------
594
595 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300596 * Fetch User Agent string
Timothy Warren40403d22012-04-19 16:38:50 -0400597 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300598 * @return string|null User Agent string or NULL if it doesn't exist
Timothy Warren40403d22012-04-19 16:38:50 -0400599 */
Andrey Andreev8850e372014-02-27 21:56:06 +0200600 public function user_agent($xss_clean = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000601 {
Andrey Andreev8850e372014-02-27 21:56:06 +0200602 return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean);
Derek Allard2067d1a2008-11-13 22:59:24 +0000603 }
604
605 // --------------------------------------------------------------------
606
607 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400608 * Sanitize Globals
609 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300610 * Internal method serving for the following purposes:
Timothy Warren40403d22012-04-19 16:38:50 -0400611 *
Andrey Andreevb78a8c72014-04-15 17:21:16 +0300612 * - Unsets $_GET data, if query strings are not enabled
Andrey Andreev1887ec62012-10-27 16:22:07 +0300613 * - Cleans POST, COOKIE and SERVER data
614 * - Standardizes newline characters to PHP_EOL
Timothy Warren40403d22012-04-19 16:38:50 -0400615 *
616 * @return void
617 */
Andrey Andreev90cfe142012-01-08 04:46:42 +0200618 protected function _sanitize_globals()
Derek Allard2067d1a2008-11-13 22:59:24 +0000619 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600620 // Is $_GET data allowed? If not we'll set the $_GET to an empty array
Alex Bilbieed944a32012-06-02 11:07:47 +0100621 if ($this->_allow_get_array === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000622 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600623 $_GET = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000624 }
Andrey Andreev9448afb2012-02-08 19:49:19 +0200625 elseif (is_array($_GET) && count($_GET) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000626 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200627 foreach ($_GET as $key => $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000628 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200629 $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
Derek Allard2067d1a2008-11-13 22:59:24 +0000630 }
631 }
632
Derek Jones69fc4fc2010-03-02 13:36:31 -0600633 // Clean $_POST Data
Andrey Andreev9448afb2012-02-08 19:49:19 +0200634 if (is_array($_POST) && count($_POST) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000635 {
Pascal Kriete5d5895f2011-02-14 13:27:07 -0500636 foreach ($_POST as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600637 {
638 $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
639 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000640 }
641
Derek Jones69fc4fc2010-03-02 13:36:31 -0600642 // Clean $_COOKIE Data
Andrey Andreev9448afb2012-02-08 19:49:19 +0200643 if (is_array($_COOKIE) && count($_COOKIE) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000644 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600645 // Also get rid of specially treated cookies that might be set by a server
646 // or silly application, that are of no use to a CI application anyway
647 // but that when present will trip our 'Disallowed Key Characters' alarm
648 // http://www.ietf.org/rfc/rfc2109.txt
649 // note that the key names below are single quoted strings, and are not PHP variables
Andrey Andreev5ac428b2014-01-08 16:07:31 +0200650 unset(
651 $_COOKIE['$Version'],
652 $_COOKIE['$Path'],
653 $_COOKIE['$Domain']
654 );
Derek Jones69fc4fc2010-03-02 13:36:31 -0600655
Pascal Kriete5d5895f2011-02-14 13:27:07 -0500656 foreach ($_COOKIE as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600657 {
Andrey Andreevfd0aabb2013-09-23 13:18:20 +0300658 if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE)
659 {
660 $_COOKIE[$cookie_key] = $this->_clean_input_data($val);
661 }
662 else
663 {
664 unset($_COOKIE[$key]);
665 }
Derek Jones69fc4fc2010-03-02 13:36:31 -0600666 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000667 }
668
Derek Jones69fc4fc2010-03-02 13:36:31 -0600669 // Sanitize PHP_SELF
670 $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
671
Derek Jones69fc4fc2010-03-02 13:36:31 -0600672 // CSRF Protection check
Andrey Andreevf964b162013-11-12 17:04:55 +0200673 if ($this->_enable_csrf === TRUE && ! is_cli())
Derek Allard2067d1a2008-11-13 22:59:24 +0000674 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600675 $this->security->csrf_verify();
Derek Allard2067d1a2008-11-13 22:59:24 +0000676 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000677
Andrey Andreevfd0aabb2013-09-23 13:18:20 +0300678 log_message('debug', 'Global POST, GET and COOKIE data sanitized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000679 }
680
681 // --------------------------------------------------------------------
682
683 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400684 * Clean Input Data
685 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300686 * Internal method that aids in escaping data and
687 * standardizing newline characters to PHP_EOL.
Timothy Warren40403d22012-04-19 16:38:50 -0400688 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300689 * @param string|string[] $str Input string(s)
Timothy Warren40403d22012-04-19 16:38:50 -0400690 * @return string
691 */
Andrey Andreev90cfe142012-01-08 04:46:42 +0200692 protected function _clean_input_data($str)
Derek Allard2067d1a2008-11-13 22:59:24 +0000693 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600694 if (is_array($str))
Derek Allard2067d1a2008-11-13 22:59:24 +0000695 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600696 $new_array = array();
Andrey Andreev1887ec62012-10-27 16:22:07 +0300697 foreach (array_keys($str) as $key)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600698 {
Andrey Andreev1887ec62012-10-27 16:22:07 +0300699 $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600700 }
701 return $new_array;
Derek Allard2067d1a2008-11-13 22:59:24 +0000702 }
703
Andrey Andreevaf728622011-10-20 10:11:59 +0300704 /* We strip slashes if magic quotes is on to keep things consistent
705
706 NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and
707 it will probably not exist in future versions at all.
708 */
709 if ( ! is_php('5.4') && get_magic_quotes_gpc())
Derek Allard2067d1a2008-11-13 22:59:24 +0000710 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600711 $str = stripslashes($str);
712 }
713
714 // Clean UTF-8 if supported
715 if (UTF8_ENABLED === TRUE)
716 {
717 $str = $this->uni->clean_string($str);
718 }
David Behler9b5df592011-08-14 21:04:17 +0200719
Pascal Kriete14a0ac62011-04-05 14:55:56 -0400720 // Remove control characters
Andrey Andreev5ac428b2014-01-08 16:07:31 +0200721 $str = remove_invisible_characters($str, FALSE);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600722
Derek Jones69fc4fc2010-03-02 13:36:31 -0600723 // Standardize newlines if needed
Eric Robertsb75e13d2013-01-27 20:10:09 -0600724 if ($this->_standardize_newlines === TRUE)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600725 {
Eric Robertsb75e13d2013-01-27 20:10:09 -0600726 return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str);
Derek Allard2067d1a2008-11-13 22:59:24 +0000727 }
728
729 return $str;
730 }
731
732 // --------------------------------------------------------------------
733
734 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400735 * Clean Keys
736 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300737 * Internal method that helps to prevent malicious users
Timothy Warren40403d22012-04-19 16:38:50 -0400738 * from trying to exploit keys we make sure that keys are
739 * only named with alpha-numeric text and a few other items.
740 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300741 * @param string $str Input string
Andrey Andreevfd0aabb2013-09-23 13:18:20 +0300742 * @param string $fatal Whether to terminate script exection
743 * or to return FALSE if an invalid
744 * key is encountered
745 * @return string|bool
Timothy Warren40403d22012-04-19 16:38:50 -0400746 */
Andrey Andreevfd0aabb2013-09-23 13:18:20 +0300747 protected function _clean_input_keys($str, $fatal = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000748 {
bigCat3c0846b2012-08-21 00:20:20 +0800749 if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
Derek Allard2067d1a2008-11-13 22:59:24 +0000750 {
Andrey Andreevfd0aabb2013-09-23 13:18:20 +0300751 if ($fatal === TRUE)
752 {
753 return FALSE;
754 }
755 else
756 {
757 set_status_header(503);
758 echo 'Disallowed Key Characters.';
Andrey Andreev7cf682a2014-03-13 14:55:45 +0200759 exit(7); // EXIT_USER_INPUT
Andrey Andreevfd0aabb2013-09-23 13:18:20 +0300760 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000761 }
762
Derek Jones69fc4fc2010-03-02 13:36:31 -0600763 // Clean UTF-8 if supported
764 if (UTF8_ENABLED === TRUE)
765 {
Andrey Andreev64e98aa2012-01-07 20:29:10 +0200766 return $this->uni->clean_string($str);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600767 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000768
Derek Jones69fc4fc2010-03-02 13:36:31 -0600769 return $str;
770 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000771
Greg Akerec2f5712010-11-15 16:22:12 -0600772 // --------------------------------------------------------------------
773
774 /**
775 * Request Headers
776 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300777 * @param bool $xss_clean Whether to apply XSS filtering
Andrey Andreev64e98aa2012-01-07 20:29:10 +0200778 * @return array
Greg Akerec2f5712010-11-15 16:22:12 -0600779 */
780 public function request_headers($xss_clean = FALSE)
781 {
CJ71cff1d2013-04-16 21:50:55 +0800782 // If header is already defined, return it immediately
783 if ( ! empty($this->headers))
784 {
785 return $this->headers;
786 }
787
Andrey Andreev1887ec62012-10-27 16:22:07 +0300788 // In Apache, you can simply call apache_request_headers()
Greg Akerec2f5712010-11-15 16:22:12 -0600789 if (function_exists('apache_request_headers'))
790 {
CJ71cff1d2013-04-16 21:50:55 +0800791 return $this->headers = apache_request_headers();
Greg Akerec2f5712010-11-15 16:22:12 -0600792 }
CJd195f222013-04-17 01:04:13 +0800793
CJ8347f912013-04-17 21:45:22 +0800794 $this->headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
CJd195f222013-04-17 01:04:13 +0800795
796 foreach ($_SERVER as $key => $val)
Greg Akerec2f5712010-11-15 16:22:12 -0600797 {
CJd195f222013-04-17 01:04:13 +0800798 if (sscanf($key, 'HTTP_%s', $header) === 1)
Greg Akerec2f5712010-11-15 16:22:12 -0600799 {
CJd195f222013-04-17 01:04:13 +0800800 // take SOME_HEADER and turn it into Some-Header
801 $header = str_replace('_', ' ', strtolower($header));
802 $header = str_replace(' ', '-', ucwords($header));
Greg Akerec2f5712010-11-15 16:22:12 -0600803
CJd195f222013-04-17 01:04:13 +0800804 $this->headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
CJ826990f2013-04-16 14:17:53 +0800805 }
Greg Akerec2f5712010-11-15 16:22:12 -0600806 }
David Behler9b5df592011-08-14 21:04:17 +0200807
Greg Akerec2f5712010-11-15 16:22:12 -0600808 return $this->headers;
809 }
810
811 // --------------------------------------------------------------------
812
813 /**
814 * Get Request Header
815 *
816 * Returns the value of a single member of the headers class member
817 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300818 * @param string $index Header name
819 * @param bool $xss_clean Whether to apply XSS filtering
Adriano Rosaf112e4a2014-10-03 13:15:46 -0300820 * @return string|null The requested header on success or NULL on failure
Greg Akerec2f5712010-11-15 16:22:12 -0600821 */
822 public function get_request_header($index, $xss_clean = FALSE)
823 {
824 if (empty($this->headers))
825 {
826 $this->request_headers();
827 }
David Behler9b5df592011-08-14 21:04:17 +0200828
Greg Akerec2f5712010-11-15 16:22:12 -0600829 if ( ! isset($this->headers[$index]))
830 {
Phil Sturgeon55a6ddb2012-05-23 18:37:24 +0100831 return NULL;
Greg Akerec2f5712010-11-15 16:22:12 -0600832 }
833
Andrey Andreev9448afb2012-02-08 19:49:19 +0200834 return ($xss_clean === TRUE)
835 ? $this->security->xss_clean($this->headers[$index])
836 : $this->headers[$index];
Greg Akerec2f5712010-11-15 16:22:12 -0600837 }
838
Greg Aker081ac9d2010-11-22 14:42:53 -0600839 // --------------------------------------------------------------------
Phil Sturgeonc3828712011-01-19 12:31:47 +0000840
Greg Aker081ac9d2010-11-22 14:42:53 -0600841 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300842 * Is AJAX request?
Greg Aker081ac9d2010-11-22 14:42:53 -0600843 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300844 * Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
Greg Aker081ac9d2010-11-22 14:42:53 -0600845 *
Andrey Andreev9448afb2012-02-08 19:49:19 +0200846 * @return bool
Greg Aker081ac9d2010-11-22 14:42:53 -0600847 */
848 public function is_ajax_request()
849 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200850 return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
Greg Aker081ac9d2010-11-22 14:42:53 -0600851 }
852
Phil Sturgeonc3828712011-01-19 12:31:47 +0000853 // --------------------------------------------------------------------
854
855 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300856 * Is CLI request?
Phil Sturgeonc3828712011-01-19 12:31:47 +0000857 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300858 * Test to see if a request was made from the command line.
Phil Sturgeonc3828712011-01-19 12:31:47 +0000859 *
Andrey Andreevf964b162013-11-12 17:04:55 +0200860 * @deprecated 3.0.0 Use is_cli() instead
861 * @return bool
Phil Sturgeonc3828712011-01-19 12:31:47 +0000862 */
863 public function is_cli_request()
864 {
Andrey Andreevf964b162013-11-12 17:04:55 +0200865 return is_cli();
Phil Sturgeonc3828712011-01-19 12:31:47 +0000866 }
867
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100868 // --------------------------------------------------------------------
869
870 /**
871 * Get Request Method
872 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300873 * Return the request method
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100874 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300875 * @param bool $upper Whether to return in upper or lower case
876 * (default: FALSE)
877 * @return string
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100878 */
Michiel Vugteveen704fb162012-03-07 20:42:33 +0100879 public function method($upper = FALSE)
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100880 {
Michiel Vugteveendc900df2012-03-07 20:41:37 +0100881 return ($upper)
882 ? strtoupper($this->server('REQUEST_METHOD'))
883 : strtolower($this->server('REQUEST_METHOD'));
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100884 }
885
Derek Allard2067d1a2008-11-13 22:59:24 +0000886}