Upgrade to KH 3.3.0
This commit is contained in:
72
includes/kohana/system/classes/Kohana/HTTP/Exception.php
Normal file
72
includes/kohana/system/classes/Kohana/HTTP/Exception.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
abstract class Kohana_HTTP_Exception extends Kohana_Exception {
|
||||
|
||||
/**
|
||||
* Creates an HTTP_Exception of the specified type.
|
||||
*
|
||||
* @param integer $code the http status code
|
||||
* @param string $message status message, custom content to display with error
|
||||
* @param array $variables translation variables
|
||||
* @return HTTP_Exception
|
||||
*/
|
||||
public static function factory($code, $message = NULL, array $variables = NULL, Exception $previous = NULL)
|
||||
{
|
||||
$class = 'HTTP_Exception_'.$code;
|
||||
|
||||
return new $class($message, $variables, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var int http status code
|
||||
*/
|
||||
protected $_code = 0;
|
||||
|
||||
/**
|
||||
* @var Request Request instance that triggered this exception.
|
||||
*/
|
||||
protected $_request;
|
||||
|
||||
/**
|
||||
* Creates a new translated exception.
|
||||
*
|
||||
* throw new Kohana_Exception('Something went terrible wrong, :user',
|
||||
* array(':user' => $user));
|
||||
*
|
||||
* @param string $message status message, custom content to display with error
|
||||
* @param array $variables translation variables
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message = NULL, array $variables = NULL, Exception $previous = NULL)
|
||||
{
|
||||
parent::__construct($message, $variables, $this->_code, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the Request that triggered this exception.
|
||||
*
|
||||
* @param Request $request Request object that triggered this exception.
|
||||
* @return Response
|
||||
*/
|
||||
public function request(Request $request = NULL)
|
||||
{
|
||||
if ($request === NULL)
|
||||
return $this->_request;
|
||||
|
||||
$this->_request = $request;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Response for the current Exception
|
||||
*
|
||||
* @uses Kohana_Exception::response()
|
||||
* @return Response
|
||||
*/
|
||||
public function get_response()
|
||||
{
|
||||
return Kohana_Exception::response($this);
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Exception
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/300.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/300.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_300 extends HTTP_Exception_Redirect {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 300 Multiple Choices
|
||||
*/
|
||||
protected $_code = 300;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/301.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/301.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_301 extends HTTP_Exception_Redirect {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 301 Moved Permanently
|
||||
*/
|
||||
protected $_code = 301;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/302.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/302.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_302 extends HTTP_Exception_Redirect {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 302 Found
|
||||
*/
|
||||
protected $_code = 302;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/303.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/303.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_303 extends HTTP_Exception_Redirect {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 303 See Other
|
||||
*/
|
||||
protected $_code = 303;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/304.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/304.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_304 extends HTTP_Exception_Expected {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 304 Not Modified
|
||||
*/
|
||||
protected $_code = 304;
|
||||
|
||||
}
|
41
includes/kohana/system/classes/Kohana/HTTP/Exception/305.php
Normal file
41
includes/kohana/system/classes/Kohana/HTTP/Exception/305.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_305 extends HTTP_Exception_Expected {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 305 Use Proxy
|
||||
*/
|
||||
protected $_code = 305;
|
||||
|
||||
/**
|
||||
* Specifies the proxy to replay this request via
|
||||
*
|
||||
* @param string $location URI of the proxy
|
||||
*/
|
||||
public function location($uri = NULL)
|
||||
{
|
||||
if ($uri === NULL)
|
||||
return $this->headers('Location');
|
||||
|
||||
$this->headers('Location', $uri);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this exception contains everything needed to continue.
|
||||
*
|
||||
* @throws Kohana_Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
if ($location = $this->headers('location') === NULL)
|
||||
throw new Kohana_Exception('A \'location\' must be specified for a redirect');
|
||||
|
||||
if (strpos($location, '://') === FALSE)
|
||||
throw new Kohana_Exception('An absolute URI to the proxy server must be specified');
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/307.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/307.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_307 extends HTTP_Exception_Redirect {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 307 Temporary Redirect
|
||||
*/
|
||||
protected $_code = 307;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/400.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/400.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_400 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 400 Bad Request
|
||||
*/
|
||||
protected $_code = 400;
|
||||
|
||||
}
|
38
includes/kohana/system/classes/Kohana/HTTP/Exception/401.php
Normal file
38
includes/kohana/system/classes/Kohana/HTTP/Exception/401.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_401 extends HTTP_Exception_Expected {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 401 Unauthorized
|
||||
*/
|
||||
protected $_code = 401;
|
||||
|
||||
/**
|
||||
* Specifies the WWW-Authenticate challenge.
|
||||
*
|
||||
* @param string $challenge WWW-Authenticate challenge (eg `Basic realm="Control Panel"`)
|
||||
*/
|
||||
public function authenticate($challenge = NULL)
|
||||
{
|
||||
if ($challenge === NULL)
|
||||
return $this->headers('www-authenticate');
|
||||
|
||||
$this->headers('www-authenticate', $challenge);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this exception contains everything needed to continue.
|
||||
*
|
||||
* @throws Kohana_Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
if ($this->headers('www-authenticate') === NULL)
|
||||
throw new Kohana_Exception('A \'www-authenticate\' header must be specified for a HTTP 401 Unauthorized');
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/402.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/402.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_402 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 402 Payment Required
|
||||
*/
|
||||
protected $_code = 402;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/403.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/403.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_403 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 403 Forbidden
|
||||
*/
|
||||
protected $_code = 403;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/404.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/404.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_404 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 404 Not Found
|
||||
*/
|
||||
protected $_code = 404;
|
||||
|
||||
}
|
41
includes/kohana/system/classes/Kohana/HTTP/Exception/405.php
Normal file
41
includes/kohana/system/classes/Kohana/HTTP/Exception/405.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_405 extends HTTP_Exception_Expected {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 405 Method Not Allowed
|
||||
*/
|
||||
protected $_code = 405;
|
||||
|
||||
/**
|
||||
* Specifies the list of allowed HTTP methods
|
||||
*
|
||||
* @param array $methods List of allowed methods
|
||||
*/
|
||||
public function allowed($methods)
|
||||
{
|
||||
if (is_array($methods))
|
||||
{
|
||||
$methods = implode(',', $methods);
|
||||
}
|
||||
|
||||
$this->headers('allow', $methods);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this exception contains everything needed to continue.
|
||||
*
|
||||
* @throws Kohana_Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
if ($location = $this->headers('allow') === NULL)
|
||||
throw new Kohana_Exception('A list of allowed methods must be specified');
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/406.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/406.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_406 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 406 Not Acceptable
|
||||
*/
|
||||
protected $_code = 406;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/407.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/407.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_407 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 407 Proxy Authentication Required
|
||||
*/
|
||||
protected $_code = 407;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/408.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/408.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_408 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 408 Request Timeout
|
||||
*/
|
||||
protected $_code = 408;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/409.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/409.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_409 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 409 Conflict
|
||||
*/
|
||||
protected $_code = 409;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/410.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/410.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_410 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 410 Gone
|
||||
*/
|
||||
protected $_code = 410;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/411.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/411.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_411 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 411 Length Required
|
||||
*/
|
||||
protected $_code = 411;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/412.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/412.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_412 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 412 Precondition Failed
|
||||
*/
|
||||
protected $_code = 412;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/413.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/413.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_413 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 413 Request Entity Too Large
|
||||
*/
|
||||
protected $_code = 413;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/414.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/414.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_414 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 414 Request-URI Too Long
|
||||
*/
|
||||
protected $_code = 414;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/415.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/415.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_415 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 415 Unsupported Media Type
|
||||
*/
|
||||
protected $_code = 415;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/416.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/416.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_416 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 416 Request Range Not Satisfiable
|
||||
*/
|
||||
protected $_code = 416;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/417.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/417.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_417 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 417 Expectation Failed
|
||||
*/
|
||||
protected $_code = 417;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/500.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/500.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_500 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 500 Internal Server Error
|
||||
*/
|
||||
protected $_code = 500;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/501.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/501.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_501 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 501 Not Implemented
|
||||
*/
|
||||
protected $_code = 501;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/502.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/502.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_502 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 502 Bad Gateway
|
||||
*/
|
||||
protected $_code = 502;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/503.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/503.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_503 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 503 Service Unavailable
|
||||
*/
|
||||
protected $_code = 503;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/504.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/504.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_504 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 504 Gateway Timeout
|
||||
*/
|
||||
protected $_code = 504;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/Kohana/HTTP/Exception/505.php
Normal file
10
includes/kohana/system/classes/Kohana/HTTP/Exception/505.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_505 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 505 HTTP Version Not Supported
|
||||
*/
|
||||
protected $_code = 505;
|
||||
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* "Expected" HTTP exception class. Used for all [HTTP_Exception]'s where a standard
|
||||
* Kohana error page should never be shown.
|
||||
*
|
||||
* Eg [HTTP_Exception_301], [HTTP_Exception_302] etc
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Exceptions
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_HTTP_Exception_Expected extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var Response Response Object
|
||||
*/
|
||||
protected $_response;
|
||||
|
||||
/**
|
||||
* Creates a new translated exception.
|
||||
*
|
||||
* throw new Kohana_Exception('Something went terrible wrong, :user',
|
||||
* array(':user' => $user));
|
||||
*
|
||||
* @param string $message status message, custom content to display with error
|
||||
* @param array $variables translation variables
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message = NULL, array $variables = NULL, Exception $previous = NULL)
|
||||
{
|
||||
parent::__construct($message, $variables, $previous);
|
||||
|
||||
// Prepare our response object and set the correct status code.
|
||||
$this->_response = Response::factory()
|
||||
->status($this->_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and sets headers to the [Response].
|
||||
*
|
||||
* @see [Response::headers]
|
||||
* @param mixed $key
|
||||
* @param string $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function headers($key = NULL, $value = NULL)
|
||||
{
|
||||
$result = $this->_response->headers($key, $value);
|
||||
|
||||
if ( ! $result instanceof Response)
|
||||
return $result;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this exception contains everything needed to continue.
|
||||
*
|
||||
* @throws Kohana_Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Response for the current Exception
|
||||
*
|
||||
* @uses Kohana_Exception::response()
|
||||
* @return Response
|
||||
*/
|
||||
public function get_response()
|
||||
{
|
||||
$this->check();
|
||||
|
||||
return $this->_response;
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Exception
|
@@ -0,0 +1,51 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* Redirect HTTP exception class. Used for all [HTTP_Exception]'s where the status
|
||||
* code indicates a redirect.
|
||||
*
|
||||
* Eg [HTTP_Exception_301], [HTTP_Exception_302] and most of the other 30x's
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Exceptions
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_HTTP_Exception_Redirect extends HTTP_Exception_Expected {
|
||||
|
||||
/**
|
||||
* Specifies the URI to redirect to.
|
||||
*
|
||||
* @param string $location URI of the proxy
|
||||
*/
|
||||
public function location($uri = NULL)
|
||||
{
|
||||
if ($uri === NULL)
|
||||
return $this->headers('Location');
|
||||
|
||||
if (strpos($uri, '://') === FALSE)
|
||||
{
|
||||
// Make the URI into a URL
|
||||
$uri = URL::site($uri, TRUE, ! empty(Kohana::$index_file));
|
||||
}
|
||||
|
||||
$this->headers('Location', $uri);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this exception contains everything needed to continue.
|
||||
*
|
||||
* @throws Kohana_Exception
|
||||
* @return bool
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
if ($this->headers('location') === NULL)
|
||||
throw new Kohana_Exception('A \'location\' must be specified for a redirect');
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Exception_Redirect
|
949
includes/kohana/system/classes/Kohana/HTTP/Header.php
Normal file
949
includes/kohana/system/classes/Kohana/HTTP/Header.php
Normal file
@@ -0,0 +1,949 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* The Kohana_HTTP_Header class provides an Object-Orientated interface
|
||||
* to HTTP headers. This can parse header arrays returned from the
|
||||
* PHP functions `apache_request_headers()` or the `http_parse_headers()`
|
||||
* function available within the PECL HTTP library.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_HTTP_Header extends ArrayObject {
|
||||
|
||||
// Default Accept-* quality value if none supplied
|
||||
const DEFAULT_QUALITY = 1;
|
||||
|
||||
/**
|
||||
* Parses an Accept(-*) header and detects the quality
|
||||
*
|
||||
* @param array $parts accept header parts
|
||||
* @return array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function accept_quality(array $parts)
|
||||
{
|
||||
$parsed = array();
|
||||
|
||||
// Resource light iteration
|
||||
$parts_keys = array_keys($parts);
|
||||
foreach ($parts_keys as $key)
|
||||
{
|
||||
$value = trim(str_replace(array("\r", "\n"), '', $parts[$key]));
|
||||
|
||||
$pattern = '~\b(\;\s*+)?q\s*+=\s*+([.0-9]+)~';
|
||||
|
||||
// If there is no quality directive, return default
|
||||
if ( ! preg_match($pattern, $value, $quality))
|
||||
{
|
||||
$parsed[$value] = (float) HTTP_Header::DEFAULT_QUALITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
$quality = $quality[2];
|
||||
|
||||
if ($quality[0] === '.')
|
||||
{
|
||||
$quality = '0'.$quality;
|
||||
}
|
||||
|
||||
// Remove the quality value from the string and apply quality
|
||||
$parsed[trim(preg_replace($pattern, '', $value, 1), '; ')] = (float) $quality;
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the accept header to provide the correct quality values
|
||||
* for each supplied accept type.
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
||||
* @param string $accepts accept content header string to parse
|
||||
* @return array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function parse_accept_header($accepts = NULL)
|
||||
{
|
||||
$accepts = explode(',', (string) $accepts);
|
||||
|
||||
// If there is no accept, lets accept everything
|
||||
if ($accepts === NULL)
|
||||
return array('*' => array('*' => (float) HTTP_Header::DEFAULT_QUALITY));
|
||||
|
||||
// Parse the accept header qualities
|
||||
$accepts = HTTP_Header::accept_quality($accepts);
|
||||
|
||||
$parsed_accept = array();
|
||||
|
||||
// This method of iteration uses less resource
|
||||
$keys = array_keys($accepts);
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
// Extract the parts
|
||||
$parts = explode('/', $key, 2);
|
||||
|
||||
// Invalid content type- bail
|
||||
if ( ! isset($parts[1]))
|
||||
continue;
|
||||
|
||||
// Set the parsed output
|
||||
$parsed_accept[$parts[0]][$parts[1]] = $accepts[$key];
|
||||
}
|
||||
|
||||
return $parsed_accept;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the `Accept-Charset:` HTTP header and returns an array containing
|
||||
* the charset and associated quality.
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2
|
||||
* @param string $charset charset string to parse
|
||||
* @return array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function parse_charset_header($charset = NULL)
|
||||
{
|
||||
if ($charset === NULL)
|
||||
{
|
||||
return array('*' => (float) HTTP_Header::DEFAULT_QUALITY);
|
||||
}
|
||||
|
||||
return HTTP_Header::accept_quality(explode(',', (string) $charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the `Accept-Encoding:` HTTP header and returns an array containing
|
||||
* the charsets and associated quality.
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
|
||||
* @param string $encoding charset string to parse
|
||||
* @return array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function parse_encoding_header($encoding = NULL)
|
||||
{
|
||||
// Accept everything
|
||||
if ($encoding === NULL)
|
||||
{
|
||||
return array('*' => (float) HTTP_Header::DEFAULT_QUALITY);
|
||||
}
|
||||
elseif ($encoding === '')
|
||||
{
|
||||
return array('identity' => (float) HTTP_Header::DEFAULT_QUALITY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HTTP_Header::accept_quality(explode(',', (string) $encoding));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the `Accept-Language:` HTTP header and returns an array containing
|
||||
* the languages and associated quality.
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
|
||||
* @param string $language charset string to parse
|
||||
* @return array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function parse_language_header($language = NULL)
|
||||
{
|
||||
if ($language === NULL)
|
||||
{
|
||||
return array('*' => array('*' => (float) HTTP_Header::DEFAULT_QUALITY));
|
||||
}
|
||||
|
||||
$language = HTTP_Header::accept_quality(explode(',', (string) $language));
|
||||
|
||||
$parsed_language = array();
|
||||
|
||||
$keys = array_keys($language);
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
// Extract the parts
|
||||
$parts = explode('-', $key, 2);
|
||||
|
||||
// Invalid content type- bail
|
||||
if ( ! isset($parts[1]))
|
||||
{
|
||||
$parsed_language[$parts[0]]['*'] = $language[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the parsed output
|
||||
$parsed_language[$parts[0]][$parts[1]] = $language[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed_language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Cache-Control HTTP header based on the supplied array.
|
||||
*
|
||||
* // Set the cache control headers you want to use
|
||||
* $cache_control = array(
|
||||
* 'max-age' => 3600,
|
||||
* 'must-revalidate',
|
||||
* 'public'
|
||||
* );
|
||||
*
|
||||
* // Create the cache control header, creates :
|
||||
* // cache-control: max-age=3600, must-revalidate, public
|
||||
* $response->headers('Cache-Control', HTTP_Header::create_cache_control($cache_control);
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13
|
||||
* @param array $cache_control Cache-Control to render to string
|
||||
* @return string
|
||||
*/
|
||||
public static function create_cache_control(array $cache_control)
|
||||
{
|
||||
$parts = array();
|
||||
|
||||
foreach ($cache_control as $key => $value)
|
||||
{
|
||||
$parts[] = (is_int($key)) ? $value : ($key.'='.$value);
|
||||
}
|
||||
|
||||
return implode(', ', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the Cache-Control header and returning an array representation of the Cache-Control
|
||||
* header.
|
||||
*
|
||||
* // Create the cache control header
|
||||
* $response->headers('cache-control', 'max-age=3600, must-revalidate, public');
|
||||
*
|
||||
* // Parse the cache control header
|
||||
* if ($cache_control = HTTP_Header::parse_cache_control($response->headers('cache-control')))
|
||||
* {
|
||||
* // Cache-Control header was found
|
||||
* $maxage = $cache_control['max-age'];
|
||||
* }
|
||||
*
|
||||
* @param array $cache_control Array of headers
|
||||
* @return mixed
|
||||
*/
|
||||
public static function parse_cache_control($cache_control)
|
||||
{
|
||||
$directives = explode(',', strtolower($cache_control));
|
||||
|
||||
if ($directives === FALSE)
|
||||
return FALSE;
|
||||
|
||||
$output = array();
|
||||
|
||||
foreach ($directives as $directive)
|
||||
{
|
||||
if (strpos($directive, '=') !== FALSE)
|
||||
{
|
||||
list($key, $value) = explode('=', trim($directive), 2);
|
||||
|
||||
$output[$key] = ctype_digit($value) ? (int) $value : $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$output[] = trim($directive);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array Accept: (content) types
|
||||
*/
|
||||
protected $_accept_content;
|
||||
|
||||
/**
|
||||
* @var array Accept-Charset: parsed header
|
||||
*/
|
||||
protected $_accept_charset;
|
||||
|
||||
/**
|
||||
* @var array Accept-Encoding: parsed header
|
||||
*/
|
||||
protected $_accept_encoding;
|
||||
|
||||
/**
|
||||
* @var array Accept-Language: parsed header
|
||||
*/
|
||||
protected $_accept_language;
|
||||
|
||||
/**
|
||||
* Constructor method for [Kohana_HTTP_Header]. Uses the standard constructor
|
||||
* of the parent `ArrayObject` class.
|
||||
*
|
||||
* $header_object = new HTTP_Header(array('x-powered-by' => 'Kohana 3.1.x', 'expires' => '...'));
|
||||
*
|
||||
* @param mixed $input Input array
|
||||
* @param int $flags Flags
|
||||
* @param string $iterator_class The iterator class to use
|
||||
*/
|
||||
public function __construct(array $input = array(), $flags = NULL, $iterator_class = 'ArrayIterator')
|
||||
{
|
||||
/**
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616.html
|
||||
*
|
||||
* HTTP header declarations should be treated as case-insensitive
|
||||
*/
|
||||
$input = array_change_key_case( (array) $input, CASE_LOWER);
|
||||
|
||||
parent::__construct($input, $flags, $iterator_class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header object as a string, including
|
||||
* the terminating new line
|
||||
*
|
||||
* // Return the header as a string
|
||||
* echo (string) $request->headers();
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$header = '';
|
||||
|
||||
foreach ($this as $key => $value)
|
||||
{
|
||||
// Put the keys back the Case-Convention expected
|
||||
$key = Text::ucfirst($key);
|
||||
|
||||
if (is_array($value))
|
||||
{
|
||||
$header .= $key.': '.(implode(', ', $value))."\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$header .= $key.': '.$value."\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $header."\r\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloads `ArrayObject::offsetSet()` to enable handling of header
|
||||
* with multiple instances of the same directive. If the `$replace` flag
|
||||
* is `FALSE`, the header will be appended rather than replacing the
|
||||
* original setting.
|
||||
*
|
||||
* @param mixed $index index to set `$newval` to
|
||||
* @param mixed $newval new value to set
|
||||
* @param boolean $replace replace existing value
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function offsetSet($index, $newval, $replace = TRUE)
|
||||
{
|
||||
// Ensure the index is lowercase
|
||||
$index = strtolower($index);
|
||||
|
||||
if ($replace OR ! $this->offsetExists($index))
|
||||
{
|
||||
return parent::offsetSet($index, $newval);
|
||||
}
|
||||
|
||||
$current_value = $this->offsetGet($index);
|
||||
|
||||
if (is_array($current_value))
|
||||
{
|
||||
$current_value[] = $newval;
|
||||
}
|
||||
else
|
||||
{
|
||||
$current_value = array($current_value, $newval);
|
||||
}
|
||||
|
||||
return parent::offsetSet($index, $current_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloads the `ArrayObject::offsetExists()` method to ensure keys
|
||||
* are lowercase.
|
||||
*
|
||||
* @param string $index
|
||||
* @return boolean
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function offsetExists($index)
|
||||
{
|
||||
return parent::offsetExists(strtolower($index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloads the `ArrayObject::offsetUnset()` method to ensure keys
|
||||
* are lowercase.
|
||||
*
|
||||
* @param string $index
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function offsetUnset($index)
|
||||
{
|
||||
return parent::offsetUnset(strtolower($index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload the `ArrayObject::offsetGet()` method to ensure that all
|
||||
* keys passed to it are formatted correctly for this object.
|
||||
*
|
||||
* @param string $index index to retrieve
|
||||
* @return mixed
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function offsetGet($index)
|
||||
{
|
||||
return parent::offsetGet(strtolower($index));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloads the `ArrayObject::exchangeArray()` method to ensure that
|
||||
* all keys are changed to lowercase.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function exchangeArray($input)
|
||||
{
|
||||
/**
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616.html
|
||||
*
|
||||
* HTTP header declarations should be treated as case-insensitive
|
||||
*/
|
||||
$input = array_change_key_case( (array) $input, CASE_LOWER);
|
||||
|
||||
return parent::exchangeArray($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a HTTP Message header line and applies it to this HTTP_Header
|
||||
*
|
||||
* $header = $response->headers();
|
||||
* $header->parse_header_string(NULL, 'content-type: application/json');
|
||||
*
|
||||
* @param resource $resource the resource (required by Curl API)
|
||||
* @param string $header_line the line from the header to parse
|
||||
* @return int
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function parse_header_string($resource, $header_line)
|
||||
{
|
||||
$headers = array();
|
||||
|
||||
if (preg_match_all('/(\w[^\s:]*):[ ]*([^\r\n]*(?:\r\n[ \t][^\r\n]*)*)/', $header_line, $matches))
|
||||
{
|
||||
foreach ($matches[0] as $key => $value)
|
||||
{
|
||||
$this->offsetSet($matches[1][$key], $matches[2][$key], FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return strlen($header_line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the accept quality of a submitted mime type based on the
|
||||
* request `Accept:` header. If the `$explicit` argument is `TRUE`,
|
||||
* only precise matches will be returned, excluding all wildcard (`*`)
|
||||
* directives.
|
||||
*
|
||||
* // Accept: application/xml; application/json; q=.5; text/html; q=.2, text/*
|
||||
* // Accept quality for application/json
|
||||
*
|
||||
* // $quality = 0.5
|
||||
* $quality = $request->headers()->accepts_at_quality('application/json');
|
||||
*
|
||||
* // $quality_explicit = FALSE
|
||||
* $quality_explicit = $request->headers()->accepts_at_quality('text/plain', TRUE);
|
||||
*
|
||||
* @param string $type
|
||||
* @param boolean $explicit explicit check, excludes `*`
|
||||
* @return mixed
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function accepts_at_quality($type, $explicit = FALSE)
|
||||
{
|
||||
// Parse Accept header if required
|
||||
if ($this->_accept_content === NULL)
|
||||
{
|
||||
if ($this->offsetExists('Accept'))
|
||||
{
|
||||
$accept = $this->offsetGet('Accept');
|
||||
}
|
||||
else
|
||||
{
|
||||
$accept = '*/*';
|
||||
}
|
||||
|
||||
$this->_accept_content = HTTP_Header::parse_accept_header($accept);
|
||||
}
|
||||
|
||||
// If not a real mime, try and find it in config
|
||||
if (strpos($type, '/') === FALSE)
|
||||
{
|
||||
$mime = Kohana::$config->load('mimes.'.$type);
|
||||
|
||||
if ($mime === NULL)
|
||||
return FALSE;
|
||||
|
||||
$quality = FALSE;
|
||||
|
||||
foreach ($mime as $_type)
|
||||
{
|
||||
$quality_check = $this->accepts_at_quality($_type, $explicit);
|
||||
$quality = ($quality_check > $quality) ? $quality_check : $quality;
|
||||
}
|
||||
|
||||
return $quality;
|
||||
}
|
||||
|
||||
$parts = explode('/', $type, 2);
|
||||
|
||||
if (isset($this->_accept_content[$parts[0]][$parts[1]]))
|
||||
{
|
||||
return $this->_accept_content[$parts[0]][$parts[1]];
|
||||
}
|
||||
elseif ($explicit === TRUE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($this->_accept_content[$parts[0]]['*']))
|
||||
{
|
||||
return $this->_accept_content[$parts[0]]['*'];
|
||||
}
|
||||
elseif (isset($this->_accept_content['*']['*']))
|
||||
{
|
||||
return $this->_accept_content['*']['*'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred response content type based on the accept header
|
||||
* quality settings. If items have the same quality value, the first item
|
||||
* found in the array supplied as `$types` will be returned.
|
||||
*
|
||||
* // Get the preferred acceptable content type
|
||||
* // Accept: text/html, application/json; q=.8, text/*
|
||||
* $result = $header->preferred_accept(array(
|
||||
* 'text/html'
|
||||
* 'text/rtf',
|
||||
* 'application/json'
|
||||
* )); // $result = 'application/json'
|
||||
*
|
||||
* $result = $header->preferred_accept(array(
|
||||
* 'text/rtf',
|
||||
* 'application/xml'
|
||||
* ), TRUE); // $result = FALSE (none matched explicitly)
|
||||
*
|
||||
*
|
||||
* @param array $types the content types to examine
|
||||
* @param boolean $explicit only allow explicit references, no wildcards
|
||||
* @return string name of the preferred content type
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function preferred_accept(array $types, $explicit = FALSE)
|
||||
{
|
||||
$preferred = FALSE;
|
||||
$ceiling = 0;
|
||||
|
||||
foreach ($types as $type)
|
||||
{
|
||||
$quality = $this->accepts_at_quality($type, $explicit);
|
||||
|
||||
if ($quality > $ceiling)
|
||||
{
|
||||
$preferred = $type;
|
||||
$ceiling = $quality;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quality of the supplied `$charset` argument. This method
|
||||
* will automatically parse the `Accept-Charset` header if present and
|
||||
* return the associated resolved quality value.
|
||||
*
|
||||
* // Accept-Charset: utf-8, utf-16; q=.8, iso-8859-1; q=.5
|
||||
* $quality = $header->accepts_charset_at_quality('utf-8');
|
||||
* // $quality = (float) 1
|
||||
*
|
||||
* @param string $charset charset to examine
|
||||
* @return float the quality of the charset
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function accepts_charset_at_quality($charset)
|
||||
{
|
||||
if ($this->_accept_charset === NULL)
|
||||
{
|
||||
if ($this->offsetExists('Accept-Charset'))
|
||||
{
|
||||
$charset_header = strtolower($this->offsetGet('Accept-Charset'));
|
||||
$this->_accept_charset = HTTP_Header::parse_charset_header($charset_header);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_accept_charset = HTTP_Header::parse_charset_header(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
$charset = strtolower($charset);
|
||||
|
||||
if (isset($this->_accept_charset[$charset]))
|
||||
{
|
||||
return $this->_accept_charset[$charset];
|
||||
}
|
||||
elseif (isset($this->_accept_charset['*']))
|
||||
{
|
||||
return $this->_accept_charset['*'];
|
||||
}
|
||||
elseif ($charset === 'iso-8859-1')
|
||||
{
|
||||
return (float) 1;
|
||||
}
|
||||
|
||||
return (float) 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred charset from the supplied array `$charsets` based
|
||||
* on the `Accept-Charset` header directive.
|
||||
*
|
||||
* // Accept-Charset: utf-8, utf-16; q=.8, iso-8859-1; q=.5
|
||||
* $charset = $header->preferred_charset(array(
|
||||
* 'utf-10', 'ascii', 'utf-16', 'utf-8'
|
||||
* )); // $charset = 'utf-8'
|
||||
*
|
||||
* @param array $charsets charsets to test
|
||||
* @return mixed preferred charset or `FALSE`
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function preferred_charset(array $charsets)
|
||||
{
|
||||
$preferred = FALSE;
|
||||
$ceiling = 0;
|
||||
|
||||
foreach ($charsets as $charset)
|
||||
{
|
||||
$quality = $this->accepts_charset_at_quality($charset);
|
||||
|
||||
if ($quality > $ceiling)
|
||||
{
|
||||
$preferred = $charset;
|
||||
$ceiling = $quality;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quality of the `$encoding` type passed to it. Encoding
|
||||
* is usually compression such as `gzip`, but could be some other
|
||||
* message encoding algorithm. This method allows explicit checks to be
|
||||
* done ignoring wildcards.
|
||||
*
|
||||
* // Accept-Encoding: compress, gzip, *; q=.5
|
||||
* $encoding = $header->accepts_encoding_at_quality('gzip');
|
||||
* // $encoding = (float) 1.0s
|
||||
*
|
||||
* @param string $encoding encoding type to interrogate
|
||||
* @param boolean $explicit explicit check, ignoring wildcards and `identity`
|
||||
* @return float
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function accepts_encoding_at_quality($encoding, $explicit = FALSE)
|
||||
{
|
||||
if ($this->_accept_encoding === NULL)
|
||||
{
|
||||
if ($this->offsetExists('Accept-Encoding'))
|
||||
{
|
||||
$encoding_header = $this->offsetGet('Accept-Encoding');
|
||||
}
|
||||
else
|
||||
{
|
||||
$encoding_header = NULL;
|
||||
}
|
||||
|
||||
$this->_accept_encoding = HTTP_Header::parse_encoding_header($encoding_header);
|
||||
}
|
||||
|
||||
// Normalize the encoding
|
||||
$encoding = strtolower($encoding);
|
||||
|
||||
if (isset($this->_accept_encoding[$encoding]))
|
||||
{
|
||||
return $this->_accept_encoding[$encoding];
|
||||
}
|
||||
|
||||
if ($explicit === FALSE)
|
||||
{
|
||||
if (isset($this->_accept_encoding['*']))
|
||||
{
|
||||
return $this->_accept_encoding['*'];
|
||||
}
|
||||
elseif ($encoding === 'identity')
|
||||
{
|
||||
return (float) HTTP_Header::DEFAULT_QUALITY;
|
||||
}
|
||||
}
|
||||
|
||||
return (float) 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred message encoding type based on quality, and can
|
||||
* optionally ignore wildcard references. If two or more encodings have the
|
||||
* same quality, the first listed in `$encodings` will be returned.
|
||||
*
|
||||
* // Accept-Encoding: compress, gzip, *; q.5
|
||||
* $encoding = $header->preferred_encoding(array(
|
||||
* 'gzip', 'bzip', 'blowfish'
|
||||
* ));
|
||||
* // $encoding = 'gzip';
|
||||
*
|
||||
* @param array $encodings encodings to test against
|
||||
* @param boolean $explicit explicit check, if `TRUE` wildcards are excluded
|
||||
* @return mixed
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function preferred_encoding(array $encodings, $explicit = FALSE)
|
||||
{
|
||||
$ceiling = 0;
|
||||
$preferred = FALSE;
|
||||
|
||||
foreach ($encodings as $encoding)
|
||||
{
|
||||
$quality = $this->accepts_encoding_at_quality($encoding, $explicit);
|
||||
|
||||
if ($quality > $ceiling)
|
||||
{
|
||||
$ceiling = $quality;
|
||||
$preferred = $encoding;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quality of `$language` supplied, optionally ignoring
|
||||
* wildcards if `$explicit` is set to a non-`FALSE` value. If the quality
|
||||
* is not found, `0.0` is returned.
|
||||
*
|
||||
* // Accept-Language: en-us, en-gb; q=.7, en; q=.5
|
||||
* $lang = $header->accepts_language_at_quality('en-gb');
|
||||
* // $lang = (float) 0.7
|
||||
*
|
||||
* $lang2 = $header->accepts_language_at_quality('en-au');
|
||||
* // $lang2 = (float) 0.5
|
||||
*
|
||||
* $lang3 = $header->accepts_language_at_quality('en-au', TRUE);
|
||||
* // $lang3 = (float) 0.0
|
||||
*
|
||||
* @param string $language language to interrogate
|
||||
* @param boolean $explicit explicit interrogation, `TRUE` ignores wildcards
|
||||
* @return float
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function accepts_language_at_quality($language, $explicit = FALSE)
|
||||
{
|
||||
if ($this->_accept_language === NULL)
|
||||
{
|
||||
if ($this->offsetExists('Accept-Language'))
|
||||
{
|
||||
$language_header = strtolower($this->offsetGet('Accept-Language'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$language_header = NULL;
|
||||
}
|
||||
|
||||
$this->_accept_language = HTTP_Header::parse_language_header($language_header);
|
||||
}
|
||||
|
||||
// Normalize the language
|
||||
$language_parts = explode('-', strtolower($language), 2);
|
||||
|
||||
if (isset($this->_accept_language[$language_parts[0]]))
|
||||
{
|
||||
if (isset($language_parts[1]))
|
||||
{
|
||||
if (isset($this->_accept_language[$language_parts[0]][$language_parts[1]]))
|
||||
{
|
||||
return $this->_accept_language[$language_parts[0]][$language_parts[1]];
|
||||
}
|
||||
elseif ($explicit === FALSE AND isset($this->_accept_language[$language_parts[0]]['*']))
|
||||
{
|
||||
return $this->_accept_language[$language_parts[0]]['*'];
|
||||
}
|
||||
}
|
||||
elseif (isset($this->_accept_language[$language_parts[0]]['*']))
|
||||
{
|
||||
return $this->_accept_language[$language_parts[0]]['*'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($explicit === FALSE AND isset($this->_accept_language['*']))
|
||||
{
|
||||
return $this->_accept_language['*'];
|
||||
}
|
||||
|
||||
return (float) 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred language from the supplied array `$languages` based
|
||||
* on the `Accept-Language` header directive.
|
||||
*
|
||||
* // Accept-Language: en-us, en-gb; q=.7, en; q=.5
|
||||
* $lang = $header->preferred_language(array(
|
||||
* 'en-gb', 'en-au', 'fr', 'es'
|
||||
* )); // $lang = 'en-gb'
|
||||
*
|
||||
* @param array $languages
|
||||
* @param boolean $explicit
|
||||
* @return mixed
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function preferred_language(array $languages, $explicit = FALSE)
|
||||
{
|
||||
$ceiling = 0;
|
||||
$preferred = FALSE;
|
||||
|
||||
foreach ($languages as $language)
|
||||
{
|
||||
$quality = $this->accepts_language_at_quality($language, $explicit);
|
||||
|
||||
if ($quality > $ceiling)
|
||||
{
|
||||
$ceiling = $quality;
|
||||
$preferred = $language;
|
||||
}
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends headers to the php processor, or supplied `$callback` argument.
|
||||
* This method formats the headers correctly for output, re-instating their
|
||||
* capitalization for transmission.
|
||||
*
|
||||
* [!!] if you supply a custom header handler via `$callback`, it is
|
||||
* recommended that `$response` is returned
|
||||
*
|
||||
* @param HTTP_Response $response header to send
|
||||
* @param boolean $replace replace existing value
|
||||
* @param callback $callback optional callback to replace PHP header function
|
||||
* @return mixed
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function send_headers(HTTP_Response $response = NULL, $replace = FALSE, $callback = NULL)
|
||||
{
|
||||
if ($response === NULL)
|
||||
{
|
||||
// Default to the initial request message
|
||||
$response = Request::initial()->response();
|
||||
}
|
||||
|
||||
$protocol = $response->protocol();
|
||||
$status = $response->status();
|
||||
|
||||
// Create the response header
|
||||
$processed_headers = array($protocol.' '.$status.' '.Response::$messages[$status]);
|
||||
|
||||
// Get the headers array
|
||||
$headers = $response->headers()->getArrayCopy();
|
||||
|
||||
foreach ($headers as $header => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$value = implode(', ', $value);
|
||||
}
|
||||
|
||||
$processed_headers[] = Text::ucfirst($header).': '.$value;
|
||||
}
|
||||
|
||||
if ( ! isset($headers['content-type']))
|
||||
{
|
||||
$processed_headers[] = 'Content-Type: '.Kohana::$content_type.'; charset='.Kohana::$charset;
|
||||
}
|
||||
|
||||
if (Kohana::$expose AND ! isset($headers['x-powered-by']))
|
||||
{
|
||||
$processed_headers[] = 'X-Powered-By: '.Kohana::version();
|
||||
}
|
||||
|
||||
// Get the cookies and apply
|
||||
if ($cookies = $response->cookie())
|
||||
{
|
||||
$processed_headers['Set-Cookie'] = $cookies;
|
||||
}
|
||||
|
||||
if (is_callable($callback))
|
||||
{
|
||||
// Use the callback method to set header
|
||||
return call_user_func($callback, $response, $processed_headers, $replace);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_send_headers_to_php($processed_headers, $replace);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the supplied headers to the PHP output buffer. If cookies
|
||||
* are included in the message they will be handled appropriately.
|
||||
*
|
||||
* @param array $headers headers to send to php
|
||||
* @param boolean $replace replace existing headers
|
||||
* @return self
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function _send_headers_to_php(array $headers, $replace)
|
||||
{
|
||||
// If the headers have been sent, get out
|
||||
if (headers_sent())
|
||||
return $this;
|
||||
|
||||
foreach ($headers as $key => $line)
|
||||
{
|
||||
if ($key == 'Set-Cookie' AND is_array($line))
|
||||
{
|
||||
// Send cookies
|
||||
foreach ($line as $name => $value)
|
||||
{
|
||||
Cookie::set($name, $value['value'], $value['expiration']);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
header($line, $replace);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Header
|
56
includes/kohana/system/classes/Kohana/HTTP/Message.php
Normal file
56
includes/kohana/system/classes/Kohana/HTTP/Message.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* The HTTP Interaction interface providing the core HTTP methods that
|
||||
* should be implemented by any HTTP request or response class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
interface Kohana_HTTP_Message {
|
||||
|
||||
/**
|
||||
* Gets or sets the HTTP protocol. The standard protocol to use
|
||||
* is `HTTP/1.1`.
|
||||
*
|
||||
* @param string $protocol Protocol to set to the request/response
|
||||
* @return mixed
|
||||
*/
|
||||
public function protocol($protocol = NULL);
|
||||
|
||||
/**
|
||||
* Gets or sets HTTP headers to the request or response. All headers
|
||||
* are included immediately after the HTTP protocol definition during
|
||||
* transmission. This method provides a simple array or key/value
|
||||
* interface to the headers.
|
||||
*
|
||||
* @param mixed $key Key or array of key/value pairs to set
|
||||
* @param string $value Value to set to the supplied key
|
||||
* @return mixed
|
||||
*/
|
||||
public function headers($key = NULL, $value = NULL);
|
||||
|
||||
/**
|
||||
* Gets or sets the HTTP body to the request or response. The body is
|
||||
* included after the header, separated by a single empty new line.
|
||||
*
|
||||
* @param string $content Content to set to the object
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
public function body($content = NULL);
|
||||
|
||||
/**
|
||||
* Renders the HTTP_Interaction to a string, producing
|
||||
*
|
||||
* - Protocol
|
||||
* - Headers
|
||||
* - Body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render();
|
||||
}
|
64
includes/kohana/system/classes/Kohana/HTTP/Request.php
Normal file
64
includes/kohana/system/classes/Kohana/HTTP/Request.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* A HTTP Request specific interface that adds the methods required
|
||||
* by HTTP requests. Over and above [Kohana_HTTP_Interaction], this
|
||||
* interface provides method, uri, get and post methods.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
interface Kohana_HTTP_Request extends HTTP_Message {
|
||||
|
||||
// HTTP Methods
|
||||
const GET = 'GET';
|
||||
const POST = 'POST';
|
||||
const PUT = 'PUT';
|
||||
const DELETE = 'DELETE';
|
||||
const HEAD = 'HEAD';
|
||||
const OPTIONS = 'OPTIONS';
|
||||
const TRACE = 'TRACE';
|
||||
const CONNECT = 'CONNECT';
|
||||
|
||||
/**
|
||||
* Gets or sets the HTTP method. Usually GET, POST, PUT or DELETE in
|
||||
* traditional CRUD applications.
|
||||
*
|
||||
* @param string $method Method to use for this request
|
||||
* @return mixed
|
||||
*/
|
||||
public function method($method = NULL);
|
||||
|
||||
/**
|
||||
* Gets the URI of this request, optionally allows setting
|
||||
* of [Route] specific parameters during the URI generation.
|
||||
* If no parameters are passed, the request will use the
|
||||
* default values defined in the Route.
|
||||
*
|
||||
* @param array $params Optional parameters to include in uri generation
|
||||
* @return string
|
||||
*/
|
||||
public function uri();
|
||||
|
||||
/**
|
||||
* Gets or sets HTTP query string.
|
||||
*
|
||||
* @param mixed $key Key or key value pairs to set
|
||||
* @param string $value Value to set to a key
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($key = NULL, $value = NULL);
|
||||
|
||||
/**
|
||||
* Gets or sets HTTP POST parameters to the request.
|
||||
*
|
||||
* @param mixed $key Key or key value pairs to set
|
||||
* @param string $value Value to set to a key
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($key = NULL, $value = NULL);
|
||||
|
||||
}
|
31
includes/kohana/system/classes/Kohana/HTTP/Response.php
Normal file
31
includes/kohana/system/classes/Kohana/HTTP/Response.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* A HTTP Reponse specific interface that adds the methods required
|
||||
* by HTTP responses. Over and above [Kohana_HTTP_Interaction], this
|
||||
* interface provides status.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
interface Kohana_HTTP_Response extends HTTP_Message {
|
||||
|
||||
/**
|
||||
* Sets or gets the HTTP status from this response.
|
||||
*
|
||||
* // Set the HTTP status to 404 Not Found
|
||||
* $response = Response::factory()
|
||||
* ->status(404);
|
||||
*
|
||||
* // Get the current status
|
||||
* $status = $response->status();
|
||||
*
|
||||
* @param integer $code Status to set to this response
|
||||
* @return mixed
|
||||
*/
|
||||
public function status($code = NULL);
|
||||
|
||||
}
|
Reference in New Issue
Block a user