Overview

Namespaces

  • api
  • config
  • database
  • PHP
  • Slim
    • Exception
    • Http
    • Middleware
  • utiliy

Classes

  • Headers
  • Request
  • Response
  • Util
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Slim - a micro PHP 5 framework
  4:  *
  5:  * @author      Josh Lockhart <info@slimframework.com>
  6:  * @copyright   2011 Josh Lockhart
  7:  * @link        http://www.slimframework.com
  8:  * @license     http://www.slimframework.com/license
  9:  * @version     2.2.0
 10:  * @package     Slim
 11:  *
 12:  * MIT LICENSE
 13:  *
 14:  * Permission is hereby granted, free of charge, to any person obtaining
 15:  * a copy of this software and associated documentation files (the
 16:  * "Software"), to deal in the Software without restriction, including
 17:  * without limitation the rights to use, copy, modify, merge, publish,
 18:  * distribute, sublicense, and/or sell copies of the Software, and to
 19:  * permit persons to whom the Software is furnished to do so, subject to
 20:  * the following conditions:
 21:  *
 22:  * The above copyright notice and this permission notice shall be
 23:  * included in all copies or substantial portions of the Software.
 24:  *
 25:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 26:  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 27:  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 28:  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 29:  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 30:  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 31:  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 32:  */
 33: namespace Slim\Http;
 34: 
 35: /**
 36:  * Slim HTTP Utilities
 37:  *
 38:  * This class provides useful methods for handling HTTP requests.
 39:  *
 40:  * @package Slim
 41:  * @author  Josh Lockhart
 42:  * @since   1.0.0
 43:  */
 44: class Util
 45: {
 46:     /**
 47:      * Strip slashes from string or array
 48:      *
 49:      * This method strips slashes from its input. By default, this method will only
 50:      * strip slashes from its input if magic quotes are enabled. Otherwise, you may
 51:      * override the magic quotes setting with either TRUE or FALSE as the send argument
 52:      * to force this method to strip or not strip slashes from its input.
 53:      *
 54:      * @var    array|string    $rawData
 55:      * @return array|string
 56:      */
 57:     public static function stripSlashesIfMagicQuotes($rawData, $overrideStripSlashes = null)
 58:     {
 59:         $strip = is_null($overrideStripSlashes) ? get_magic_quotes_gpc() : $overrideStripSlashes;
 60:         if ($strip) {
 61:             return self::_stripSlashes($rawData);
 62:         } else {
 63:             return $rawData;
 64:         }
 65:     }
 66: 
 67:     /**
 68:      * Strip slashes from string or array
 69:      * @param  array|string $rawData
 70:      * @return array|string
 71:      */
 72:     protected static function _stripSlashes($rawData)
 73:     {
 74:         return is_array($rawData) ? array_map(array('self', '_stripSlashes'), $rawData) : stripslashes($rawData);
 75:     }
 76: 
 77:     /**
 78:      * Encrypt data
 79:      *
 80:      * This method will encrypt data using a given key, vector, and cipher.
 81:      * By default, this will encrypt data using the RIJNDAEL/AES 256 bit cipher. You
 82:      * may override the default cipher and cipher mode by passing your own desired
 83:      * cipher and cipher mode as the final key-value array argument.
 84:      *
 85:      * @param  string $data     The unencrypted data
 86:      * @param  string $key      The encryption key
 87:      * @param  string $iv       The encryption initialization vector
 88:      * @param  array  $settings Optional key-value array with custom algorithm and mode
 89:      * @return string
 90:      */
 91:     public static function encrypt($data, $key, $iv, $settings = array())
 92:     {
 93:         if ($data === '' || !extension_loaded('mcrypt')) {
 94:             return $data;
 95:         }
 96: 
 97:         //Merge settings with defaults
 98:         $settings = array_merge(array(
 99:             'algorithm' => MCRYPT_RIJNDAEL_256,
100:             'mode' => MCRYPT_MODE_CBC
101:         ), $settings);
102: 
103:         //Get module
104:         $module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], '');
105: 
106:         //Validate IV
107:         $ivSize = mcrypt_enc_get_iv_size($module);
108:         if (strlen($iv) > $ivSize) {
109:             $iv = substr($iv, 0, $ivSize);
110:         }
111: 
112:         //Validate key
113:         $keySize = mcrypt_enc_get_key_size($module);
114:         if (strlen($key) > $keySize) {
115:             $key = substr($key, 0, $keySize);
116:         }
117: 
118:         //Encrypt value
119:         mcrypt_generic_init($module, $key, $iv);
120:         $res = @mcrypt_generic($module, $data);
121:         mcrypt_generic_deinit($module);
122: 
123:         return $res;
124:     }
125: 
126:     /**
127:      * Decrypt data
128:      *
129:      * This method will decrypt data using a given key, vector, and cipher.
130:      * By default, this will decrypt data using the RIJNDAEL/AES 256 bit cipher. You
131:      * may override the default cipher and cipher mode by passing your own desired
132:      * cipher and cipher mode as the final key-value array argument.
133:      *
134:      * @param  string $data     The encrypted data
135:      * @param  string $key      The encryption key
136:      * @param  string $iv       The encryption initialization vector
137:      * @param  array  $settings Optional key-value array with custom algorithm and mode
138:      * @return string
139:      */
140:     public static function decrypt($data, $key, $iv, $settings = array())
141:     {
142:         if ($data === '' || !extension_loaded('mcrypt')) {
143:             return $data;
144:         }
145: 
146:         //Merge settings with defaults
147:         $settings = array_merge(array(
148:             'algorithm' => MCRYPT_RIJNDAEL_256,
149:             'mode' => MCRYPT_MODE_CBC
150:         ), $settings);
151: 
152:         //Get module
153:         $module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], '');
154: 
155:         //Validate IV
156:         $ivSize = mcrypt_enc_get_iv_size($module);
157:         if (strlen($iv) > $ivSize) {
158:             $iv = substr($iv, 0, $ivSize);
159:         }
160: 
161:         //Validate key
162:         $keySize = mcrypt_enc_get_key_size($module);
163:         if (strlen($key) > $keySize) {
164:             $key = substr($key, 0, $keySize);
165:         }
166: 
167:         //Decrypt value
168:         mcrypt_generic_init($module, $key, $iv);
169:         $decryptedData = @mdecrypt_generic($module, $data);
170:         $res = str_replace("\x0", '', $decryptedData);
171:         mcrypt_generic_deinit($module);
172: 
173:         return $res;
174:     }
175: 
176:     /**
177:      * Encode secure cookie value
178:      *
179:      * This method will create the secure value of an HTTP cookie. The
180:      * cookie value is encrypted and hashed so that its value is
181:      * secure and checked for integrity when read in subsequent requests.
182:      *
183:      * @param string $value     The unsecure HTTP cookie value
184:      * @param int    $expires   The UNIX timestamp at which this cookie will expire
185:      * @param string $secret    The secret key used to hash the cookie value
186:      * @param int    $algorithm The algorithm to use for encryption
187:      * @param int    $mode      The algorithm mode to use for encryption
188:      * @param string
189:      */
190:     public static function encodeSecureCookie($value, $expires, $secret, $algorithm, $mode)
191:     {
192:         $key = hash_hmac('sha1', $expires, $secret);
193:         $iv = self::get_iv($expires, $secret);
194:         $secureString = base64_encode(self::encrypt($value, $key, $iv, array(
195:             'algorithm' => $algorithm,
196:             'mode' => $mode
197:         )));
198:         $verificationString = hash_hmac('sha1', $expires . $value, $key);
199: 
200:         return implode('|', array($expires, $secureString, $verificationString));
201:     }
202: 
203:     /**
204:      * Decode secure cookie value
205:      *
206:      * This method will decode the secure value of an HTTP cookie. The
207:      * cookie value is encrypted and hashed so that its value is
208:      * secure and checked for integrity when read in subsequent requests.
209:      *
210:      * @param string $value     The secure HTTP cookie value
211:      * @param int    $expires   The UNIX timestamp at which this cookie will expire
212:      * @param string $secret    The secret key used to hash the cookie value
213:      * @param int    $algorithm The algorithm to use for encryption
214:      * @param int    $mode      The algorithm mode to use for encryption
215:      * @param string
216:      */
217:     public static function decodeSecureCookie($value, $secret, $algorithm, $mode)
218:     {
219:         if ($value) {
220:             $value = explode('|', $value);
221:             if (count($value) === 3 && ((int) $value[0] === 0 || (int) $value[0] > time())) {
222:                 $key = hash_hmac('sha1', $value[0], $secret);
223:                 $iv = self::get_iv($value[0], $secret);
224:                 $data = self::decrypt(base64_decode($value[1]), $key, $iv, array(
225:                     'algorithm' => $algorithm,
226:                     'mode' => $mode
227:                 ));
228:                 $verificationString = hash_hmac('sha1', $value[0] . $data, $key);
229:                 if ($verificationString === $value[2]) {
230:                     return $data;
231:                 }
232:             }
233:         }
234: 
235:         return false;
236:     }
237: 
238:     /**
239:      * Set HTTP cookie header
240:      *
241:      * This method will construct and set the HTTP `Set-Cookie` header. Slim
242:      * uses this method instead of PHP's native `setcookie` method. This allows
243:      * more control of the HTTP header irrespective of the native implementation's
244:      * dependency on PHP versions.
245:      *
246:      * This method accepts the Slim_Http_Headers object by reference as its
247:      * first argument; this method directly modifies this object instead of
248:      * returning a value.
249:      *
250:      * @param  array  $header
251:      * @param  string $name
252:      * @param  string $value
253:      */
254:     public static function setCookieHeader(&$header, $name, $value)
255:     {
256:         //Build cookie header
257:         if (is_array($value)) {
258:             $domain = '';
259:             $path = '';
260:             $expires = '';
261:             $secure = '';
262:             $httponly = '';
263:             if (isset($value['domain']) && $value['domain']) {
264:                 $domain = '; domain=' . $value['domain'];
265:             }
266:             if (isset($value['path']) && $value['path']) {
267:                 $path = '; path=' . $value['path'];
268:             }
269:             if (isset($value['expires'])) {
270:                 if (is_string($value['expires'])) {
271:                     $timestamp = strtotime($value['expires']);
272:                 } else {
273:                     $timestamp = (int) $value['expires'];
274:                 }
275:                 if ($timestamp !== 0) {
276:                     $expires = '; expires=' . gmdate('D, d-M-Y H:i:s e', $timestamp);
277:                 }
278:             }
279:             if (isset($value['secure']) && $value['secure']) {
280:                 $secure = '; secure';
281:             }
282:             if (isset($value['httponly']) && $value['httponly']) {
283:                 $httponly = '; HttpOnly';
284:             }
285:             $cookie = sprintf('%s=%s%s', urlencode($name), urlencode((string) $value['value']), $domain . $path . $expires . $secure . $httponly);
286:         } else {
287:             $cookie = sprintf('%s=%s', urlencode($name), urlencode((string) $value));
288:         }
289: 
290:         //Set cookie header
291:         if (!isset($header['Set-Cookie']) || $header['Set-Cookie'] === '') {
292:             $header['Set-Cookie'] = $cookie;
293:         } else {
294:             $header['Set-Cookie'] = implode("\n", array($header['Set-Cookie'], $cookie));
295:         }
296:     }
297: 
298:     /**
299:      * Delete HTTP cookie header
300:      *
301:      * This method will construct and set the HTTP `Set-Cookie` header to invalidate
302:      * a client-side HTTP cookie. If a cookie with the same name (and, optionally, domain)
303:      * is already set in the HTTP response, it will also be removed. Slim uses this method
304:      * instead of PHP's native `setcookie` method. This allows more control of the HTTP header
305:      * irrespective of PHP's native implementation's dependency on PHP versions.
306:      *
307:      * This method accepts the Slim_Http_Headers object by reference as its
308:      * first argument; this method directly modifies this object instead of
309:      * returning a value.
310:      *
311:      * @param  array  $header
312:      * @param  string $name
313:      * @param  string $value
314:      */
315:     public static function deleteCookieHeader(&$header, $name, $value = array())
316:     {
317:         //Remove affected cookies from current response header
318:         $cookiesOld = array();
319:         $cookiesNew = array();
320:         if (isset($header['Set-Cookie'])) {
321:             $cookiesOld = explode("\n", $header['Set-Cookie']);
322:         }
323:         foreach ($cookiesOld as $c) {
324:             if (isset($value['domain']) && $value['domain']) {
325:                 $regex = sprintf('@%s=.*domain=%s@', urlencode($name), preg_quote($value['domain']));
326:             } else {
327:                 $regex = sprintf('@%s=@', urlencode($name));
328:             }
329:             if (preg_match($regex, $c) === 0) {
330:                 $cookiesNew[] = $c;
331:             }
332:         }
333:         if ($cookiesNew) {
334:             $header['Set-Cookie'] = implode("\n", $cookiesNew);
335:         } else {
336:             unset($header['Set-Cookie']);
337:         }
338: 
339:         //Set invalidating cookie to clear client-side cookie
340:         self::setCookieHeader($header, $name, array_merge(array('value' => '', 'path' => null, 'domain' => null, 'expires' => time() - 100), $value));
341:     }
342: 
343:     /**
344:      * Parse cookie header
345:      *
346:      * This method will parse the HTTP requst's `Cookie` header
347:      * and extract cookies into an associative array.
348:      *
349:      * @param  string
350:      * @return array
351:      */
352:     public static function parseCookieHeader($header)
353:     {
354:         $cookies = array();
355:         $header = rtrim($header, "\r\n");
356:         $headerPieces = preg_split('@\s*[;,]\s*@', $header);
357:         foreach ($headerPieces as $c) {
358:             $cParts = explode('=', $c);
359:             if (count($cParts) === 2) {
360:                 $key = urldecode($cParts[0]);
361:                 $value = urldecode($cParts[1]);
362:                 if (!isset($cookies[$key])) {
363:                     $cookies[$key] = $value;
364:                 }
365:             }
366:         }
367: 
368:         return $cookies;
369:     }
370: 
371:     /**
372:      * Generate a random IV
373:      *
374:      * This method will generate a non-predictable IV for use with
375:      * the cookie encryption
376:      *
377:      * @param  int    $expires The UNIX timestamp at which this cookie will expire
378:      * @param  string $secret  The secret key used to hash the cookie value
379:      * @return binary string with length 40
380:      */
381:     private static function get_iv($expires, $secret)
382:     {
383:         $data1 = hash_hmac('sha1', 'a'.$expires.'b', $secret);
384:         $data2 = hash_hmac('sha1', 'z'.$expires.'y', $secret);
385: 
386:         return pack("h*", $data1.$data2);
387:     }
388: 
389: }
390: 
GeoApi API documentation generated by ApiGen 2.8.0