blob: ffe7b4d278a35b48127784280a1b5149e51e2294 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev64e98aa2012-01-07 20:29:10 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev64e98aa2012-01-07 20:29:10 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * 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 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Andrey Andreev80500af2013-01-01 08:16:53 +020021 * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
30 * Input Class
31 *
32 * Pre-processes global input data for security
33 *
34 * @package CodeIgniter
35 * @subpackage Libraries
36 * @category Input
Derek Jonesf4a4bd82011-10-20 12:18:42 -050037 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000038 * @link http://codeigniter.com/user_guide/libraries/input.html
39 */
40class CI_Input {
Derek Allard2067d1a2008-11-13 22:59:24 +000041
David Behler9b5df592011-08-14 21:04:17 +020042 /**
43 * IP address of the current user
44 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030045 * @var string
David Behler9b5df592011-08-14 21:04:17 +020046 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030047 public $ip_address = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030048
David Behler9b5df592011-08-14 21:04:17 +020049 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +030050 * User agent strin
David Behler9b5df592011-08-14 21:04:17 +020051 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030052 * @var string
David Behler9b5df592011-08-14 21:04:17 +020053 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030054 public $user_agent = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030055
David Behler9b5df592011-08-14 21:04:17 +020056 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +030057 * Allow GET array flag
David Behler9b5df592011-08-14 21:04:17 +020058 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030059 * If set to FALSE, then $_GET will be set to an empty array.
David Behler9b5df592011-08-14 21:04:17 +020060 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030061 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020062 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030063 protected $_allow_get_array = TRUE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030064
David Behler9b5df592011-08-14 21:04:17 +020065 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +030066 * Standartize new lines flag
David Behler9b5df592011-08-14 21:04:17 +020067 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030068 * If set to TRUE, then newlines are standardized.
69 *
70 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020071 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030072 protected $_standardize_newlines = TRUE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030073
David Behler9b5df592011-08-14 21:04:17 +020074 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +030075 * Enable XSS flag
76 *
77 * Determines whether the XSS filter is always active when
78 * GET, POST or COOKIE data is encountered.
79 * Set automatically based on config setting.
80 *
81 * @var bool
82 */
83 protected $_enable_xss = FALSE;
84
85 /**
86 * Enable CSRF flag
87 *
David Behler9b5df592011-08-14 21:04:17 +020088 * Enables a CSRF cookie token to be set.
Andrey Andreev1887ec62012-10-27 16:22:07 +030089 * Set automatically based on config setting.
David Behler9b5df592011-08-14 21:04:17 +020090 *
Andrey Andreev1887ec62012-10-27 16:22:07 +030091 * @var bool
David Behler9b5df592011-08-14 21:04:17 +020092 */
Andrey Andreev1887ec62012-10-27 16:22:07 +030093 protected $_enable_csrf = FALSE;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030094
David Behler9b5df592011-08-14 21:04:17 +020095 /**
96 * List of all HTTP request headers
97 *
98 * @var array
99 */
Andrey Andreev1887ec62012-10-27 16:22:07 +0300100 protected $headers = array();
David Behler9b5df592011-08-14 21:04:17 +0200101
Derek Allard2067d1a2008-11-13 22:59:24 +0000102 /**
Andrey Andreev303eef02012-11-06 14:55:48 +0200103 * Input stream data
104 *
105 * Parsed from php://input at runtime
106 *
107 * @see CI_Input::input_stream()
108 * @var array
109 */
110 protected $_input_stream = NULL;
111
112 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300113 * Class constructor
Greg Akera9263282010-11-10 15:26:43 -0600114 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300115 * Determines whether to globally enable the XSS processing
116 * and whether to allow the $_GET array.
Andrey Andreev92ebfb62012-05-17 12:49:24 +0300117 *
118 * @return void
Greg Akera9263282010-11-10 15:26:43 -0600119 */
120 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +0000121 {
Andrey Andreev13774972012-01-08 04:30:33 +0200122 log_message('debug', 'Input Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000123
Phil Sturgeonc8089152010-12-27 19:06:28 +0000124 $this->_allow_get_array = (config_item('allow_get_array') === TRUE);
Andrey Andreev64e98aa2012-01-07 20:29:10 +0200125 $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
126 $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600127
Pascal Kriete14a0ac62011-04-05 14:55:56 -0400128 global $SEC;
129 $this->security =& $SEC;
Derek Jones69fc4fc2010-03-02 13:36:31 -0600130
Pascal Krieteaaec1e42011-01-20 00:01:21 -0500131 // Do we need the UTF-8 class?
Derek Jones69fc4fc2010-03-02 13:36:31 -0600132 if (UTF8_ENABLED === TRUE)
133 {
134 global $UNI;
135 $this->uni =& $UNI;
136 }
137
138 // Sanitize global arrays
Derek Allard2067d1a2008-11-13 22:59:24 +0000139 $this->_sanitize_globals();
140 }
141
142 // --------------------------------------------------------------------
143
144 /**
Greg Akera9263282010-11-10 15:26:43 -0600145 * Fetch from array
146 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300147 * Internal method used to retrieve values from global arrays.
Greg Akera9263282010-11-10 15:26:43 -0600148 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300149 * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc.
150 * @param string $index Index for item to be fetched from $array
151 * @param bool $xss_clean Whether to apply XSS filtering
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530152 * @param bool $recurse Whether to recurse into arrays via nested keys
Andrey Andreev1887ec62012-10-27 16:22:07 +0300153 * @return mixed
Greg Akera9263282010-11-10 15:26:43 -0600154 */
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530155 protected function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE, $recurse = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000156 {
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530157 $value = NULL;
158
159 if (isset($array[$index]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000160 {
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530161 $value = $array[$index];
162 }
163 else if($recurse)
164 {
165 // We couldn't find the $field as a simple key, so try the nested notation
166 $key = $index;
167 $container = $array;
168
169 // Test if the $index is an array name, and try to obtain the final index
170 if (preg_match_all('/\[(.*?)\]/', $index, $matches))
171 {
172 sscanf($index, '%[^[][', $key);
173 for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
174 {
175 if($matches[1][$i] === '') // The array notation will return the value as array
176 {
177 break;
178 }
179 if (isset($container[$key]))
180 {
181 $container = $container[$key];
182 $key = $matches[1][$i];
183 }
184 else
185 {
186 $container = array();
187 break;
188 }
189 }
190
191 // Check if the deepest container has the field
192 if(isset($container[$key]))
193 {
194 $value = $container[$key];
195 }
196 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 }
198
199 if ($xss_clean === TRUE)
200 {
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530201 return $this->security->xss_clean($value);
Derek Allard2067d1a2008-11-13 22:59:24 +0000202 }
203
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530204 return $value;
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 }
206
207 // --------------------------------------------------------------------
208
209 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400210 * Fetch an item from the GET array
211 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300212 * @param string $index Index for item to be fetched from $_GET
213 * @param bool $xss_clean Whether to apply XSS filtering
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530214 * @param bool $recurse Whether to recurse into arrays via nested keys
Andrey Andreev1887ec62012-10-27 16:22:07 +0300215 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400216 */
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530217 public function get($index = NULL, $xss_clean = FALSE, $recurse = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000219 // Check if a field has been provided
Andrey Andreev77bd21b2012-11-20 16:34:15 +0200220 if ($index === NULL)
vascopjff1cfa12011-02-13 21:30:19 +0000221 {
Andrey Andreev77bd21b2012-11-20 16:34:15 +0200222 if (empty($_GET))
223 {
224 return array();
225 }
226
Phil Sturgeon44f21052011-02-15 21:39:25 +0000227 $get = array();
vascopjff1cfa12011-02-13 21:30:19 +0000228
229 // loop through the full _GET array
Phil Sturgeon44f21052011-02-15 21:39:25 +0000230 foreach (array_keys($_GET) as $key)
vascopjff1cfa12011-02-13 21:30:19 +0000231 {
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530232 $get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean, $recurse);
vascopjff1cfa12011-02-13 21:30:19 +0000233 }
Phil Sturgeon44f21052011-02-15 21:39:25 +0000234 return $get;
vascopjff1cfa12011-02-13 21:30:19 +0000235 }
236
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530237 return $this->_fetch_from_array($_GET, $index, $xss_clean, $recurse);
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 }
239
240 // --------------------------------------------------------------------
241
242 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400243 * Fetch an item from the POST array
244 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300245 * @param string $index Index for item to be fetched from $_POST
246 * @param bool $xss_clean Whether to apply XSS filtering
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530247 * @param bool $recurse Whether to recurse into arrays via nested keys
Andrey Andreev1887ec62012-10-27 16:22:07 +0300248 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400249 */
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530250 public function post($index = NULL, $xss_clean = FALSE, $recurse = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000251 {
Phil Sturgeon44f21052011-02-15 21:39:25 +0000252 // Check if a field has been provided
Andrey Andreev77bd21b2012-11-20 16:34:15 +0200253 if ($index === NULL)
vascopj0ba58b82011-02-06 14:20:21 +0000254 {
Andrey Andreev77bd21b2012-11-20 16:34:15 +0200255 if (empty($_POST))
256 {
257 return array();
258 }
259
Phil Sturgeon44f21052011-02-15 21:39:25 +0000260 $post = array();
vascopj0ba58b82011-02-06 14:20:21 +0000261
Phil Sturgeon44f21052011-02-15 21:39:25 +0000262 // Loop through the full _POST array and return it
263 foreach (array_keys($_POST) as $key)
vascopj0ba58b82011-02-06 14:20:21 +0000264 {
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530265 $post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean, $recurse);
vascopj0ba58b82011-02-06 14:20:21 +0000266 }
Phil Sturgeon44f21052011-02-15 21:39:25 +0000267 return $post;
vascopj0ba58b82011-02-06 14:20:21 +0000268 }
David Behler9b5df592011-08-14 21:04:17 +0200269
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530270 return $this->_fetch_from_array($_POST, $index, $xss_clean, $recurse);
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 }
272
273 // --------------------------------------------------------------------
274
275 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300276 * Fetch an item from POST data with fallback to GET
Timothy Warren40403d22012-04-19 16:38:50 -0400277 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300278 * @param string $index Index for item to be fetched from $_POST or $_GET
279 * @param bool $xss_clean Whether to apply XSS filtering
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530280 * @param bool $recurse Whether to recurse into arrays via nested keys
Andrey Andreev1887ec62012-10-27 16:22:07 +0300281 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400282 */
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530283 public function get_post($index = '', $xss_clean = FALSE, $recurse = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200285 return isset($_POST[$index])
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530286 ? $this->post($index, $xss_clean, $recurse)
287 : $this->get($index, $xss_clean, $recurse);
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 }
289
290 // --------------------------------------------------------------------
291
292 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400293 * Fetch an item from the COOKIE array
294 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300295 * @param string $index Index for item to be fetched from $_COOKIE
296 * @param bool $xss_clean Whether to apply XSS filtering
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530297 * @param bool $recurse Whether to recurse into arrays via nested keys
Andrey Andreev1887ec62012-10-27 16:22:07 +0300298 * @return mixed
Timothy Warren40403d22012-04-19 16:38:50 -0400299 */
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530300 public function cookie($index = '', $xss_clean = FALSE, $recurse = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 {
nisheeth-barthwala7447d22013-03-21 15:48:10 +0530302 return $this->_fetch_from_array($_COOKIE, $index, $xss_clean, $recurse);
Derek Allard2067d1a2008-11-13 22:59:24 +0000303 }
304
Andrey Andreev1887ec62012-10-27 16:22:07 +0300305 // --------------------------------------------------------------------
306
307 /**
308 * Fetch an item from the SERVER array
309 *
310 * @param string $index Index for item to be fetched from $_SERVER
311 * @param bool $xss_clean Whether to apply XSS filtering
312 * @return mixed
313 */
314 public function server($index = '', $xss_clean = FALSE)
315 {
316 return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
317 }
318
Derek Jones69fc4fc2010-03-02 13:36:31 -0600319 // ------------------------------------------------------------------------
320
321 /**
Andrey Andreev303eef02012-11-06 14:55:48 +0200322 * Fetch an item from the php://input stream
323 *
324 * Useful when you need to access PUT, DELETE or PATCH request data.
325 *
326 * @param string $index Index for item to be fetched
327 * @param bool $xss_clean Whether to apply XSS filtering
328 * @return mixed
329 */
330 public function input_stream($index = '', $xss_clean = FALSE)
331 {
332 // The input stream can only be read once, so we'll need to check
333 // if we have already done that first.
334 if (is_array($this->_input_stream))
335 {
336 return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
337 }
338
339 // Parse the input stream in our cache var
340 parse_str(file_get_contents('php://input'), $this->_input_stream);
341 if ( ! is_array($this->_input_stream))
342 {
343 $this->_input_stream = array();
344 return NULL;
345 }
346
347 return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
348 }
349
350 // ------------------------------------------------------------------------
351
352 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400353 * Set cookie
354 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300355 * Accepts an arbitrary number of parameters (up to 7) or an associative
Timothy Warren40403d22012-04-19 16:38:50 -0400356 * array in the first parameter containing all the values.
357 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300358 * @param string|mixed[] $name Cookie name or an array containing parameters
359 * @param string $value Cookie value
360 * @param int $expire Cookie expiration time in seconds
361 * @param string $domain Cookie domain (e.g.: '.yourdomain.com')
362 * @param string $path Cookie path (default: '/')
363 * @param string $prefix Cookie name prefix
364 * @param bool $secure Whether to only transfer cookies via SSL
365 * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript)
Timothy Warren40403d22012-04-19 16:38:50 -0400366 * @return void
367 */
freewil4ad0fd82012-03-13 22:37:42 -0400368 public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600369 {
370 if (is_array($name))
371 {
tobiasbg9aa7dc92011-02-18 21:57:13 +0100372 // always leave 'name' in last place, as the loop will break otherwise, due to $$item
freewil4ad0fd82012-03-13 22:37:42 -0400373 foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'httponly', 'name') as $item)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600374 {
375 if (isset($name[$item]))
376 {
377 $$item = $name[$item];
378 }
379 }
380 }
381
Alex Bilbieed944a32012-06-02 11:07:47 +0100382 if ($prefix === '' && config_item('cookie_prefix') !== '')
Derek Jones69fc4fc2010-03-02 13:36:31 -0600383 {
384 $prefix = config_item('cookie_prefix');
385 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300386
387 if ($domain == '' && config_item('cookie_domain') != '')
Derek Jones69fc4fc2010-03-02 13:36:31 -0600388 {
389 $domain = config_item('cookie_domain');
390 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300391
Alex Bilbieed944a32012-06-02 11:07:47 +0100392 if ($path === '/' && config_item('cookie_path') !== '/')
Derek Jones69fc4fc2010-03-02 13:36:31 -0600393 {
394 $path = config_item('cookie_path');
395 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300396
Alex Bilbieed944a32012-06-02 11:07:47 +0100397 if ($secure === FALSE && config_item('cookie_secure') !== FALSE)
tobiasbg9aa7dc92011-02-18 21:57:13 +0100398 {
399 $secure = config_item('cookie_secure');
400 }
Andrey Andreev9ba661b2012-06-04 14:44:34 +0300401
Alex Bilbieed944a32012-06-02 11:07:47 +0100402 if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE)
freewil4ad0fd82012-03-13 22:37:42 -0400403 {
404 $httponly = config_item('cookie_httponly');
405 }
Derek Jones69fc4fc2010-03-02 13:36:31 -0600406
407 if ( ! is_numeric($expire))
408 {
409 $expire = time() - 86500;
410 }
411 else
412 {
Phil Sturgeonc8089152010-12-27 19:06:28 +0000413 $expire = ($expire > 0) ? time() + $expire : 0;
Derek Jones69fc4fc2010-03-02 13:36:31 -0600414 }
415
freewil4ad0fd82012-03-13 22:37:42 -0400416 setcookie($prefix.$name, $value, $expire, $path, $domain, $secure, $httponly);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600417 }
418
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 // --------------------------------------------------------------------
420
421 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400422 * Fetch the IP Address
423 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300424 * Determines and validates the visitor's IP address.
425 *
426 * @return string IP address
Timothy Warren40403d22012-04-19 16:38:50 -0400427 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800428 public function ip_address()
Derek Allard2067d1a2008-11-13 22:59:24 +0000429 {
430 if ($this->ip_address !== FALSE)
431 {
432 return $this->ip_address;
433 }
Barry Mienydd671972010-10-04 16:33:58 +0200434
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300435 $proxy_ips = config_item('proxy_ips');
Andrey Andreevea7a8662012-10-09 13:36:31 +0300436 if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300437 {
438 $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
439 }
Andrey Andreev5b92ae12012-10-04 13:05:03 +0300440
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300441 $this->ip_address = $this->server('REMOTE_ADDR');
442
443 if ($proxy_ips)
444 {
445 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 -0300446 {
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300447 if (($spoof = $this->server($header)) !== NULL)
Jordan Pittman8960acf2012-07-23 09:05:49 -0300448 {
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300449 // Some proxies typically list the whole chain of IP
450 // addresses through which the client has reached us.
451 // e.g. client_ip, proxy_ip1, proxy_ip2, etc.
Andrey Andreeve24eed72012-11-02 23:33:45 +0200452 sscanf($spoof, '%[^,]', $spoof);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300453
454 if ( ! $this->valid_ip($spoof))
455 {
456 $spoof = NULL;
457 }
458 else
459 {
Jordan Pittmana5a71352012-07-20 19:36:43 -0300460 break;
461 }
462 }
Andrey Andreev5b92ae12012-10-04 13:05:03 +0300463 }
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300464
Andrey Andreeve45ad2b2012-10-09 13:11:15 +0300465 if ($spoof)
Andrey Andreev5b92ae12012-10-04 13:05:03 +0300466 {
Andrey Andreev9df35b42012-10-09 13:37:58 +0300467 for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300468 {
469 // Check if we have an IP address or a subnet
470 if (strpos($proxy_ips[$i], '/') === FALSE)
471 {
472 // An IP address (and not a subnet) is specified.
473 // We can compare right away.
474 if ($proxy_ips[$i] === $this->ip_address)
475 {
476 $this->ip_address = $spoof;
477 break;
478 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000479
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300480 continue;
481 }
482
483 // We have a subnet ... now the heavy lifting begins
484 isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
485
486 // If the proxy entry doesn't match the IP protocol - skip it
487 if (strpos($proxy_ips[$i], $separator) === FALSE)
488 {
489 continue;
490 }
491
492 // Convert the REMOTE_ADDR IP address to binary, if needed
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300493 if ( ! isset($ip, $sprintf))
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300494 {
495 if ($separator === ':')
496 {
497 // Make sure we're have the "full" IPv6 format
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300498 $ip = explode(':',
499 str_replace('::',
500 str_repeat(':', 9 - substr_count($this->ip_address, ':')),
501 $this->ip_address
502 )
503 );
504
505 for ($i = 0; $i < 8; $i++)
506 {
507 $ip[$i] = intval($ip[$i], 16);
508 }
509
510 $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300511 }
512 else
513 {
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300514 $ip = explode('.', $this->ip_address);
515 $sprintf = '%08b%08b%08b%08b';
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300516 }
517
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300518 $ip = vsprintf($sprintf, $ip);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300519 }
520
521 // Split the netmask length off the network address
Andrey Andreeve24eed72012-11-02 23:33:45 +0200522 sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300523
524 // Again, an IPv6 address is most likely in a compressed form
525 if ($separator === ':')
526 {
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300527 $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
528 for ($i = 0; $i < 8; $i++)
529 {
530 $netaddr[$i] = intval($netaddr[$i], 16);
531 }
532 }
533 else
534 {
535 $netaddr = explode('.', $netaddr);
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300536 }
537
Andrey Andreev82d2cf12012-10-13 12:38:42 +0300538 // Convert to binary and finally compare
539 if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0)
Andrey Andreev9ac557f2012-10-06 20:27:57 +0300540 {
541 $this->ip_address = $spoof;
542 break;
543 }
544 }
545 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 }
547
Derek Allard2067d1a2008-11-13 22:59:24 +0000548 if ( ! $this->valid_ip($this->ip_address))
549 {
Andrey Andreev64e98aa2012-01-07 20:29:10 +0200550 return $this->ip_address = '0.0.0.0';
Derek Allard2067d1a2008-11-13 22:59:24 +0000551 }
552
553 return $this->ip_address;
554 }
555
556 // --------------------------------------------------------------------
557
558 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400559 * Validate IP Address
560 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300561 * @param string $ip IP address
562 * @param string $which IP protocol: 'ipv4' or 'ipv6'
Timothy Warren40403d22012-04-19 16:38:50 -0400563 * @return bool
564 */
Andrey Andreev5a257182012-06-10 06:18:14 +0300565 public function valid_ip($ip, $which = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000566 {
Andrey Andreev5a257182012-06-10 06:18:14 +0300567 switch (strtolower($which))
568 {
569 case 'ipv4':
570 $which = FILTER_FLAG_IPV4;
571 break;
572 case 'ipv6':
573 $which = FILTER_FLAG_IPV6;
574 break;
575 default:
576 $which = NULL;
577 break;
578 }
579
580 return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which);
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 }
582
583 // --------------------------------------------------------------------
584
585 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300586 * Fetch User Agent string
Timothy Warren40403d22012-04-19 16:38:50 -0400587 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300588 * @return string|null User Agent string or NULL if it doesn't exist
Timothy Warren40403d22012-04-19 16:38:50 -0400589 */
Bo-Yi Wu4db872f2011-09-12 10:52:37 +0800590 public function user_agent()
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 {
592 if ($this->user_agent !== FALSE)
593 {
594 return $this->user_agent;
595 }
596
Andrey Andreev1887ec62012-10-27 16:22:07 +0300597 return $this->user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : NULL;
Derek Allard2067d1a2008-11-13 22:59:24 +0000598 }
599
600 // --------------------------------------------------------------------
601
602 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400603 * Sanitize Globals
604 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300605 * Internal method serving for the following purposes:
Timothy Warren40403d22012-04-19 16:38:50 -0400606 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300607 * - Unsets $_GET data (if query strings are not enabled)
608 * - Unsets all globals if register_globals is enabled
609 * - Cleans POST, COOKIE and SERVER data
610 * - Standardizes newline characters to PHP_EOL
Timothy Warren40403d22012-04-19 16:38:50 -0400611 *
612 * @return void
613 */
Andrey Andreev90cfe142012-01-08 04:46:42 +0200614 protected function _sanitize_globals()
Derek Allard2067d1a2008-11-13 22:59:24 +0000615 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600616 // It would be "wrong" to unset any of these GLOBALS.
Timothy Warren40403d22012-04-19 16:38:50 -0400617 $protected = array(
618 '_SERVER',
619 '_GET',
620 '_POST',
621 '_FILES',
622 '_REQUEST',
623 '_SESSION',
624 '_ENV',
625 'GLOBALS',
626 'HTTP_RAW_POST_DATA',
627 'system_folder',
628 'application_folder',
629 'BM',
630 'EXT',
631 'CFG',
632 'URI',
633 'RTR',
Timothy Warren67cb3ee2012-04-19 16:41:52 -0400634 'OUT',
Timothy Warren40403d22012-04-19 16:38:50 -0400635 'IN'
636 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000637
Andrey Andreev1887ec62012-10-27 16:22:07 +0300638 // Unset globals for security.
Derek Jones69fc4fc2010-03-02 13:36:31 -0600639 // This is effectively the same as register_globals = off
Andrey Andreev1887ec62012-10-27 16:22:07 +0300640 // PHP 5.4 no longer has the register_globals functionality.
641 if ( ! is_php('5.4'))
Derek Allard2067d1a2008-11-13 22:59:24 +0000642 {
Andrey Andreev1887ec62012-10-27 16:22:07 +0300643 foreach (array($_GET, $_POST, $_COOKIE) as $global)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600644 {
Andrey Andreev1887ec62012-10-27 16:22:07 +0300645 if (is_array($global))
Derek Jones69fc4fc2010-03-02 13:36:31 -0600646 {
Andrey Andreev1887ec62012-10-27 16:22:07 +0300647 foreach ($global as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600648 {
Andrey Andreev1887ec62012-10-27 16:22:07 +0300649 if ( ! in_array($key, $protected))
650 {
651 global $$key;
652 $$key = NULL;
653 }
Derek Jones69fc4fc2010-03-02 13:36:31 -0600654 }
655 }
Andrey Andreev1887ec62012-10-27 16:22:07 +0300656 elseif ( ! in_array($global, $protected))
657 {
658 global $$global;
659 $$global = NULL;
660 }
Andrey Andreev92ebfb62012-05-17 12:49:24 +0300661 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000662 }
663
Derek Jones69fc4fc2010-03-02 13:36:31 -0600664 // Is $_GET data allowed? If not we'll set the $_GET to an empty array
Alex Bilbieed944a32012-06-02 11:07:47 +0100665 if ($this->_allow_get_array === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000666 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600667 $_GET = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000668 }
Andrey Andreev9448afb2012-02-08 19:49:19 +0200669 elseif (is_array($_GET) && count($_GET) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000670 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200671 foreach ($_GET as $key => $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000672 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200673 $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
Derek Allard2067d1a2008-11-13 22:59:24 +0000674 }
675 }
676
Derek Jones69fc4fc2010-03-02 13:36:31 -0600677 // Clean $_POST Data
Andrey Andreev9448afb2012-02-08 19:49:19 +0200678 if (is_array($_POST) && count($_POST) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000679 {
Pascal Kriete5d5895f2011-02-14 13:27:07 -0500680 foreach ($_POST as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600681 {
682 $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
683 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000684 }
685
Derek Jones69fc4fc2010-03-02 13:36:31 -0600686 // Clean $_COOKIE Data
Andrey Andreev9448afb2012-02-08 19:49:19 +0200687 if (is_array($_COOKIE) && count($_COOKIE) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000688 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600689 // Also get rid of specially treated cookies that might be set by a server
690 // or silly application, that are of no use to a CI application anyway
691 // but that when present will trip our 'Disallowed Key Characters' alarm
692 // http://www.ietf.org/rfc/rfc2109.txt
693 // note that the key names below are single quoted strings, and are not PHP variables
694 unset($_COOKIE['$Version']);
695 unset($_COOKIE['$Path']);
696 unset($_COOKIE['$Domain']);
697
Pascal Kriete5d5895f2011-02-14 13:27:07 -0500698 foreach ($_COOKIE as $key => $val)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600699 {
700 $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
701 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000702 }
703
Derek Jones69fc4fc2010-03-02 13:36:31 -0600704 // Sanitize PHP_SELF
705 $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
706
Derek Jones69fc4fc2010-03-02 13:36:31 -0600707 // CSRF Protection check
Andrey Andreeve45ad2b2012-10-09 13:11:15 +0300708 if ($this->_enable_csrf === TRUE && ! $this->is_cli_request())
Derek Allard2067d1a2008-11-13 22:59:24 +0000709 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600710 $this->security->csrf_verify();
Derek Allard2067d1a2008-11-13 22:59:24 +0000711 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000712
Andrey Andreev90cfe142012-01-08 04:46:42 +0200713 log_message('debug', 'Global POST and COOKIE data sanitized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000714 }
715
716 // --------------------------------------------------------------------
717
718 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400719 * Clean Input Data
720 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300721 * Internal method that aids in escaping data and
722 * standardizing newline characters to PHP_EOL.
Timothy Warren40403d22012-04-19 16:38:50 -0400723 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300724 * @param string|string[] $str Input string(s)
Timothy Warren40403d22012-04-19 16:38:50 -0400725 * @return string
726 */
Andrey Andreev90cfe142012-01-08 04:46:42 +0200727 protected function _clean_input_data($str)
Derek Allard2067d1a2008-11-13 22:59:24 +0000728 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600729 if (is_array($str))
Derek Allard2067d1a2008-11-13 22:59:24 +0000730 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600731 $new_array = array();
Andrey Andreev1887ec62012-10-27 16:22:07 +0300732 foreach (array_keys($str) as $key)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600733 {
Andrey Andreev1887ec62012-10-27 16:22:07 +0300734 $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600735 }
736 return $new_array;
Derek Allard2067d1a2008-11-13 22:59:24 +0000737 }
738
Andrey Andreevaf728622011-10-20 10:11:59 +0300739 /* We strip slashes if magic quotes is on to keep things consistent
740
741 NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and
742 it will probably not exist in future versions at all.
743 */
744 if ( ! is_php('5.4') && get_magic_quotes_gpc())
Derek Allard2067d1a2008-11-13 22:59:24 +0000745 {
Derek Jones69fc4fc2010-03-02 13:36:31 -0600746 $str = stripslashes($str);
747 }
748
749 // Clean UTF-8 if supported
750 if (UTF8_ENABLED === TRUE)
751 {
752 $str = $this->uni->clean_string($str);
753 }
David Behler9b5df592011-08-14 21:04:17 +0200754
Pascal Kriete14a0ac62011-04-05 14:55:56 -0400755 // Remove control characters
756 $str = remove_invisible_characters($str);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600757
758 // Should we filter the input data?
759 if ($this->_enable_xss === TRUE)
760 {
761 $str = $this->security->xss_clean($str);
762 }
763
764 // Standardize newlines if needed
Eric Robertsb75e13d2013-01-27 20:10:09 -0600765 if ($this->_standardize_newlines === TRUE)
Derek Jones69fc4fc2010-03-02 13:36:31 -0600766 {
Eric Robertsb75e13d2013-01-27 20:10:09 -0600767 return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str);
Derek Allard2067d1a2008-11-13 22:59:24 +0000768 }
769
770 return $str;
771 }
772
773 // --------------------------------------------------------------------
774
775 /**
Timothy Warren40403d22012-04-19 16:38:50 -0400776 * Clean Keys
777 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300778 * Internal method that helps to prevent malicious users
Timothy Warren40403d22012-04-19 16:38:50 -0400779 * from trying to exploit keys we make sure that keys are
780 * only named with alpha-numeric text and a few other items.
781 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300782 * @param string $str Input string
Timothy Warren40403d22012-04-19 16:38:50 -0400783 * @return string
784 */
Andrey Andreev90cfe142012-01-08 04:46:42 +0200785 protected function _clean_input_keys($str)
Derek Allard2067d1a2008-11-13 22:59:24 +0000786 {
bigCat3c0846b2012-08-21 00:20:20 +0800787 if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
Derek Allard2067d1a2008-11-13 22:59:24 +0000788 {
Kevin Cuppd63e4012012-02-05 14:14:32 -0500789 set_status_header(503);
Daniel Hunsaker353f9832013-01-24 17:09:10 -0700790 echo 'Disallowed Key Characters.';
Daniel Hunsaker3b5b7f42013-02-22 19:17:56 -0700791 exit(EXIT_USER_INPUT);
Derek Allard2067d1a2008-11-13 22:59:24 +0000792 }
793
Derek Jones69fc4fc2010-03-02 13:36:31 -0600794 // Clean UTF-8 if supported
795 if (UTF8_ENABLED === TRUE)
796 {
Andrey Andreev64e98aa2012-01-07 20:29:10 +0200797 return $this->uni->clean_string($str);
Derek Jones69fc4fc2010-03-02 13:36:31 -0600798 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000799
Derek Jones69fc4fc2010-03-02 13:36:31 -0600800 return $str;
801 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000802
Greg Akerec2f5712010-11-15 16:22:12 -0600803 // --------------------------------------------------------------------
804
805 /**
806 * Request Headers
807 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300808 * @param bool $xss_clean Whether to apply XSS filtering
Andrey Andreev64e98aa2012-01-07 20:29:10 +0200809 * @return array
Greg Akerec2f5712010-11-15 16:22:12 -0600810 */
811 public function request_headers($xss_clean = FALSE)
812 {
Andrey Andreev1887ec62012-10-27 16:22:07 +0300813 // In Apache, you can simply call apache_request_headers()
Greg Akerec2f5712010-11-15 16:22:12 -0600814 if (function_exists('apache_request_headers'))
815 {
816 $headers = apache_request_headers();
817 }
818 else
819 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200820 $headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
Greg Akerec2f5712010-11-15 16:22:12 -0600821
822 foreach ($_SERVER as $key => $val)
823 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200824 if (sscanf($key, 'HTTP_%s', $header) === 1)
Greg Akerec2f5712010-11-15 16:22:12 -0600825 {
Andrey Andreev7a7ad782012-11-12 17:21:01 +0200826 $headers[$header] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
Greg Akerec2f5712010-11-15 16:22:12 -0600827 }
828 }
829 }
830
831 // take SOME_HEADER and turn it into Some-Header
832 foreach ($headers as $key => $val)
833 {
Daniel Hunsakerc82b57b2012-12-31 09:22:07 -0700834 $key = str_replace(array('_', '-'), ' ', strtolower($key));
Greg Akerec2f5712010-11-15 16:22:12 -0600835 $key = str_replace(' ', '-', ucwords($key));
David Behler9b5df592011-08-14 21:04:17 +0200836
Greg Akerec2f5712010-11-15 16:22:12 -0600837 $this->headers[$key] = $val;
838 }
David Behler9b5df592011-08-14 21:04:17 +0200839
Greg Akerec2f5712010-11-15 16:22:12 -0600840 return $this->headers;
841 }
842
843 // --------------------------------------------------------------------
844
845 /**
846 * Get Request Header
847 *
848 * Returns the value of a single member of the headers class member
849 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300850 * @param string $index Header name
851 * @param bool $xss_clean Whether to apply XSS filtering
852 * @return string|bool The requested header on success or FALSE on failure
Greg Akerec2f5712010-11-15 16:22:12 -0600853 */
854 public function get_request_header($index, $xss_clean = FALSE)
855 {
856 if (empty($this->headers))
857 {
858 $this->request_headers();
859 }
David Behler9b5df592011-08-14 21:04:17 +0200860
Greg Akerec2f5712010-11-15 16:22:12 -0600861 if ( ! isset($this->headers[$index]))
862 {
Phil Sturgeon55a6ddb2012-05-23 18:37:24 +0100863 return NULL;
Greg Akerec2f5712010-11-15 16:22:12 -0600864 }
865
Andrey Andreev9448afb2012-02-08 19:49:19 +0200866 return ($xss_clean === TRUE)
867 ? $this->security->xss_clean($this->headers[$index])
868 : $this->headers[$index];
Greg Akerec2f5712010-11-15 16:22:12 -0600869 }
870
Greg Aker081ac9d2010-11-22 14:42:53 -0600871 // --------------------------------------------------------------------
Phil Sturgeonc3828712011-01-19 12:31:47 +0000872
Greg Aker081ac9d2010-11-22 14:42:53 -0600873 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300874 * Is AJAX request?
Greg Aker081ac9d2010-11-22 14:42:53 -0600875 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300876 * Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
Greg Aker081ac9d2010-11-22 14:42:53 -0600877 *
Andrey Andreev9448afb2012-02-08 19:49:19 +0200878 * @return bool
Greg Aker081ac9d2010-11-22 14:42:53 -0600879 */
880 public function is_ajax_request()
881 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200882 return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
Greg Aker081ac9d2010-11-22 14:42:53 -0600883 }
884
Phil Sturgeonc3828712011-01-19 12:31:47 +0000885 // --------------------------------------------------------------------
886
887 /**
Andrey Andreev1887ec62012-10-27 16:22:07 +0300888 * Is CLI request?
Phil Sturgeonc3828712011-01-19 12:31:47 +0000889 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300890 * Test to see if a request was made from the command line.
Phil Sturgeonc3828712011-01-19 12:31:47 +0000891 *
Andrey Andreev9448afb2012-02-08 19:49:19 +0200892 * @return bool
Phil Sturgeonc3828712011-01-19 12:31:47 +0000893 */
894 public function is_cli_request()
895 {
Andrey Andreev9448afb2012-02-08 19:49:19 +0200896 return (php_sapi_name() === 'cli' OR defined('STDIN'));
Phil Sturgeonc3828712011-01-19 12:31:47 +0000897 }
898
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100899 // --------------------------------------------------------------------
900
901 /**
902 * Get Request Method
903 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300904 * Return the request method
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100905 *
Andrey Andreev1887ec62012-10-27 16:22:07 +0300906 * @param bool $upper Whether to return in upper or lower case
907 * (default: FALSE)
908 * @return string
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100909 */
Michiel Vugteveen704fb162012-03-07 20:42:33 +0100910 public function method($upper = FALSE)
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100911 {
Michiel Vugteveendc900df2012-03-07 20:41:37 +0100912 return ($upper)
913 ? strtoupper($this->server('REQUEST_METHOD'))
914 : strtolower($this->server('REQUEST_METHOD'));
Michiel Vugteveenbe0ca262012-03-07 19:09:51 +0100915 }
916
Derek Allard2067d1a2008-11-13 22:59:24 +0000917}
Derek Allard2067d1a2008-11-13 22:59:24 +0000918
919/* End of file Input.php */
Timothy Warren40403d22012-04-19 16:38:50 -0400920/* Location: ./system/core/Input.php */