Request
Kohana_Request

Class Contents

Class declared in SYSPATH/classes/request.php on line 3.

Properties

public $action
public static $client_ip
string(14) "38.107.179.220"
public $controller
public static $current
object Request(9) {
    public route => object Route(4) {
        protected _uri => string(19) "guide/api(/<class>)"
        protected _regex => array(1) (
            "class" => string(13) "[a-zA-Z0-9_]+"
        )
        protected _defaults => array(3) (
            "controller" => string(9) "userguide"
            "action" => string(3) "api"
            "class" => NULL
        )
        protected _route_regex => string(45) "#^guide/api(?:/(?P<class>[a-zA-Z0-9_]+))?$#uD"
    }
    public status => integer 200
    public response => object View(2) {
        protected _file => string(93) "/home/b/biakaveron/ko3.biakaveron.tmweb.ru/ko3/modules/userguide/views/userguide/template.php"
        protected _data => array(7) (
            "title" => string(7) "Request"
            "content" => object View(2) {
                protected _file => string(94) "/home/b/biakaveron/ko3.biakaveron.tmweb.ru/ko3/modules/userguide/views/userguide/api/class.php"
                protected _data => array(2) (
                    "doc" => object Kodoc_Class(5) {
                        public class => object ReflectionClass(1) {
                            public name => string(7) "Request"
                        }
                        public modifiers => NULL
                        public description => string(0) ""
                        public tags => array(0) 
                        public constants => array(0) 
                    }
                    "route" => object Route(4) {
                        protected _uri => string(19) "guide/api(/<class>)"
                        protected _regex => array(1) (
                            ...
                        )
                        protected _defaults => array(3) (
                            ...
                        )
                        protected _route_regex => string(45) "#^guide/api(?:/(?P<class>[a-zA-Z0-9_]+))?$#uD"
                    }
                )
            }
            "menu" => object View(2) {
                protected _file => string(93) "/home/b/biakaveron/ko3.biakaveron.tmweb.ru/ko3/modules/userguide/views/userguide/api/menu.php"
                protected _data => array(1) (
                    "menu" => array(1) (
                        ...
                    )
                )
            }
            "breadcrumb" => array(3) (
                "guide" => string(10) "User Guide"
                "guide/api" => string(11) "API Browser"
                0 => string(7) "Request"
            )
            "styles" => array(5) (
                "guide/media/css/print.css" => string(5) "print"
                "guide/media/css/screen.css" => string(6) "screen"
                "guide/media/css/kodoc.css" => string(6) "screen"
                "guide/media/css/shCore.css" => string(6) "screen"
                "guide/media/css/shThemeKodoc.css" => string(6) "screen"
            )
            "scripts" => array(4) (
                0 => string(28) "guide/media/js/jquery.min.js"
                1 => string(23) "guide/media/js/kodoc.js"
                2 => string(24) "guide/media/js/shCore.js"
                3 => string(28) "guide/media/js/shBrushPhp.js"
            )
            "translations" => array(8) (
                "de-de" => string(7) "Deutsch"
                "en-us" => string(7) "English"
                "es-es" => string(8) "Español"
                "zh-cn" => string(12) "简体中文"
                "ru-ru" => string(14) "Русский"
                "fr-fr" => string(9) "Français"
                "he-il" => string(10) "עברית"
                "nl" => string(10) "Nederlands"
            )
        )
    }
    public headers => array(1) (
        "Content-Type" => string(24) "text/html; charset=utf-8"
    )
    public directory => string(0) ""
    public controller => string(9) "userguide"
    public action => string(3) "api"
    public uri => string(17) "guide/api/Request"
    protected _params => array(1) (
        "class" => string(7) "Request"
    )
}
public $directory
public $headers
public static $instance
object Request(9) {
    public route => object Route(4) {
        protected _uri => string(19) "guide/api(/<class>)"
        protected _regex => array(1) (
            "class" => string(13) "[a-zA-Z0-9_]+"
        )
        protected _defaults => array(3) (
            "controller" => string(9) "userguide"
            "action" => string(3) "api"
            "class" => NULL
        )
        protected _route_regex => string(45) "#^guide/api(?:/(?P<class>[a-zA-Z0-9_]+))?$#uD"
    }
    public status => integer 200
    public response => object View(2) {
        protected _file => string(93) "/home/b/biakaveron/ko3.biakaveron.tmweb.ru/ko3/modules/userguide/views/userguide/template.php"
        protected _data => array(7) (
            "title" => string(7) "Request"
            "content" => object View(2) {
                protected _file => string(94) "/home/b/biakaveron/ko3.biakaveron.tmweb.ru/ko3/modules/userguide/views/userguide/api/class.php"
                protected _data => array(2) (
                    "doc" => object Kodoc_Class(5) {
                        public class => object ReflectionClass(1) {
                            public name => string(7) "Request"
                        }
                        public modifiers => NULL
                        public description => string(0) ""
                        public tags => array(0) 
                        public constants => array(0) 
                    }
                    "route" => object Route(4) {
                        protected _uri => string(19) "guide/api(/<class>)"
                        protected _regex => array(1) (
                            ...
                        )
                        protected _defaults => array(3) (
                            ...
                        )
                        protected _route_regex => string(45) "#^guide/api(?:/(?P<class>[a-zA-Z0-9_]+))?$#uD"
                    }
                )
            }
            "menu" => object View(2) {
                protected _file => string(93) "/home/b/biakaveron/ko3.biakaveron.tmweb.ru/ko3/modules/userguide/views/userguide/api/menu.php"
                protected _data => array(1) (
                    "menu" => array(1) (
                        ...
                    )
                )
            }
            "breadcrumb" => array(3) (
                "guide" => string(10) "User Guide"
                "guide/api" => string(11) "API Browser"
                0 => string(7) "Request"
            )
            "styles" => array(5) (
                "guide/media/css/print.css" => string(5) "print"
                "guide/media/css/screen.css" => string(6) "screen"
                "guide/media/css/kodoc.css" => string(6) "screen"
                "guide/media/css/shCore.css" => string(6) "screen"
                "guide/media/css/shThemeKodoc.css" => string(6) "screen"
            )
            "scripts" => array(4) (
                0 => string(28) "guide/media/js/jquery.min.js"
                1 => string(23) "guide/media/js/kodoc.js"
                2 => string(24) "guide/media/js/shCore.js"
                3 => string(28) "guide/media/js/shBrushPhp.js"
            )
            "translations" => array(8) (
                "de-de" => string(7) "Deutsch"
                "en-us" => string(7) "English"
                "es-es" => string(8) "Español"
                "zh-cn" => string(12) "简体中文"
                "ru-ru" => string(14) "Русский"
                "fr-fr" => string(9) "Français"
                "he-il" => string(10) "עברית"
                "nl" => string(10) "Nederlands"
            )
        )
    }
    public headers => array(1) (
        "Content-Type" => string(24) "text/html; charset=utf-8"
    )
    public directory => string(0) ""
    public controller => string(9) "userguide"
    public action => string(3) "api"
    public uri => string(17) "guide/api/Request"
    protected _params => array(1) (
        "class" => string(7) "Request"
    )
}
public static $is_ajax
bool FALSE
public static $messages
array(46) (
    100 => string(8) "Continue"
    101 => string(19) "Switching Protocols"
    200 => string(2) "OK"
    201 => string(7) "Created"
    202 => string(8) "Accepted"
    203 => string(29) "Non-Authoritative Information"
    204 => string(10) "No Content"
    205 => string(13) "Reset Content"
    206 => string(15) "Partial Content"
    207 => string(12) "Multi-Status"
    300 => string(16) "Multiple Choices"
    301 => string(17) "Moved Permanently"
    302 => string(5) "Found"
    303 => string(9) "See Other"
    304 => string(12) "Not Modified"
    305 => string(9) "Use Proxy"
    307 => string(18) "Temporary Redirect"
    400 => string(11) "Bad Request"
    401 => string(12) "Unauthorized"
    402 => string(16) "Payment Required"
    403 => string(9) "Forbidden"
    404 => string(9) "Not Found"
    405 => string(18) "Method Not Allowed"
    406 => string(14) "Not Acceptable"
    407 => string(29) "Proxy Authentication Required"
    408 => string(15) "Request Timeout"
    409 => string(8) "Conflict"
    410 => string(4) "Gone"
    411 => string(15) "Length Required"
    412 => string(19) "Precondition Failed"
    413 => string(24) "Request Entity Too Large"
    414 => string(20) "Request-URI Too Long"
    415 => string(22) "Unsupported Media Type"
    416 => string(31) "Requested Range Not Satisfiable"
    417 => string(18) "Expectation Failed"
    422 => string(20) "Unprocessable Entity"
    423 => string(6) "Locked"
    424 => string(17) "Failed Dependency"
    500 => string(21) "Internal Server Error"
    501 => string(15) "Not Implemented"
    502 => string(11) "Bad Gateway"
    503 => string(19) "Service Unavailable"
    504 => string(15) "Gateway Timeout"
    505 => string(26) "HTTP Version Not Supported"
    507 => string(20) "Insufficient Storage"
    509 => string(24) "Bandwidth Limit Exceeded"
)
public static $method
string(3) "GET"
public static $protocol
string(4) "http"
public static $referrer
NULL
public $response
public $route
public $status
public $uri
public static $user_agent
string(48) "CCBot/1.0 (+http://www.commoncrawl.org/bot.html)"

Methods

public __construct( )
Kohana_Request

Source Code
public function __construct($uri)
{
	// Remove trailing slashes from the URI
	$uri = trim($uri, '/');

	// Load routes
	$routes = Route::all();

	foreach ($routes as $name => $route)
	{
		if ($params = $route->matches($uri))
		{
			// Store the URI
			$this->uri = $uri;

			// Store the matching route
			$this->route = $route;

			if (isset($params['directory']))
			{
				// Controllers are in a sub-directory
				$this->directory = $params['directory'];
			}

			// Store the controller
			$this->controller = $params['controller'];

			if (isset($params['action']))
			{
				// Store the action
				$this->action = $params['action'];
			}
			else
			{
				// Use the default action
				$this->action = Route::$default_action;
			}

			// These are accessible as public vars and can be overloaded
			unset($params['controller'], $params['action'], $params['directory']);

			// Params cannot be changed once matched
			$this->_params = $params;

			return;
		}
	}

	// No matching route for this URI
	$this->status = 404;

	throw new Kohana_Request_Exception('Unable to find a route to match the URI: :uri',
		array(':uri' => $uri));
}

public __toString( )
Kohana_Request

Source Code
public function __toString()
{
	return (string) $this->response;
}

protected _calculate_byte_range( )
Kohana_Request

Source Code
protected function _calculate_byte_range($size)
{
	// Defaults to start with when the HTTP_RANGE header doesn't exist.
	$start = 0;
	$end = $size - 1;

	if ($range = $this->_parse_byte_range())
	{
		// We have a byte range from HTTP_RANGE
		$start = $range[1];

		if ($start[0] === '-')
		{
			// A negative value means we start from the end, so -500 would be the
			// last 500 bytes.
			$start = $size - abs($start);
		}

		if (isset($range[2]))
		{
			// Set the end range
			$end = $range[2];
		}
	}

	// Normalize values.
	$start = abs(intval($start));

	// Keep the the end value in bounds and normalize it.
	$end = min(abs(intval($end)), $size - 1);

	// Keep the start in bounds.
	$start = ($end < $start) ? 0 : max($start, 0);

	return array($start, $end);
}

protected static _parse_accept( )
Kohana_Request

Source Code
protected static function _parse_accept( & $header, array $accepts = NULL)
{
	if ( ! empty($header))
	{
		// Get all of the types
		$types = explode(',', $header);

		foreach ($types as $type)
		{
			// Split the type into parts
			$parts = explode(';', $type);

			// Make the type only the MIME
			$type = trim(array_shift($parts));

			// Default quality is 1.0
			$quality = 1.0;

			foreach ($parts as $part)
			{
				// Prevent undefined $value notice below
				if (strpos($part, '=') === FALSE)
					continue;

				// Separate the key and value
				list ($key, $value) = explode('=', trim($part));

				if ($key === 'q')
				{
					// There is a quality for this type
					$quality = (float) trim($value);
				}
			}

			// Add the accept type and quality
			$accepts[$type] = $quality;
		}
	}

	// Make sure that accepts is an array
	$accepts = (array) $accepts;

	// Order by quality
	arsort($accepts);

	return $accepts;
}

protected _parse_byte_range( )
Kohana_Request

Source Code
protected function _parse_byte_range()
{
	if ( ! isset($_SERVER['HTTP_RANGE']))
	{
		return FALSE;
	}

	// TODO, speed this up with the use of string functions.
	preg_match_all('/(-?[0-9]++(?:-(?![0-9]++))?)(?:-?([0-9]++))?/', $_SERVER['HTTP_RANGE'], $matches, PREG_SET_ORDER);

	return $matches[0];
}

public static accept_encoding( )
Kohana_Request

Source Code
public static function accept_encoding($type = NULL)
{
	static $accepts;

	if ($accepts === NULL)
	{
		// Parse the HTTP_ACCEPT_LANGUAGE header
		$accepts = Request::_parse_accept($_SERVER['HTTP_ACCEPT_ENCODING']);
	}

	if (isset($type))
	{
		// Return the quality setting for this type
		return isset($accepts[$type]) ? $accepts[$type] : FALSE;
	}

	return $accepts;
}

public static accept_lang( )
Kohana_Request

Source Code
public static function accept_lang($lang = NULL)
{
	static $accepts;

	if ($accepts === NULL)
	{
		// Parse the HTTP_ACCEPT_LANGUAGE header
		$accepts = Request::_parse_accept($_SERVER['HTTP_ACCEPT_LANGUAGE']);
	}

	if (isset($lang))
	{
		// Return the quality setting for this lang
		return isset($accepts[$lang]) ? $accepts[$lang] : FALSE;
	}

	return $accepts;
}

public static accept_type( )
Kohana_Request

Source Code
public static function accept_type($type = NULL)
{
	static $accepts;

	if ($accepts === NULL)
	{
		// Parse the HTTP_ACCEPT header
		$accepts = Request::_parse_accept($_SERVER['HTTP_ACCEPT'], array('*/*' => 1.0));
	}

	if (isset($type))
	{
		// Return the quality setting for this type
		return isset($accepts[$type]) ? $accepts[$type] : $accepts['*/*'];
	}

	return $accepts;
}

public check_cache( )
Kohana_Request

Source Code
public function check_cache($etag = null)
{
	if (empty($etag))
	{
		$etag = $this->generate_etag();
	}

	// Set the ETag header
	$this->headers['ETag'] = $etag;

	// Add the Cache-Control header if it is not already set
	// This allows etags to be used with Max-Age, etc
	$this->headers += array(
		'Cache-Control' => 'must-revalidate',
	);

	if (isset($_SERVER['HTTP_IF_NONE_MATCH']) AND $_SERVER['HTTP_IF_NONE_MATCH'] === $etag)
	{
		// No need to send data again
		$this->status = 304;
		$this->send_headers();

		// Stop execution
		exit;
	}

	return $this;
}

public static current( )
Kohana_Request

Source Code
public static function current()
{
	return Request::$current;
}

public static detect_uri( )
Kohana_Request

Source Code
public static function detect_uri()
{
	if ( ! empty($_SERVER['PATH_INFO']))
	{
		// PATH_INFO does not contain the docroot or index
		$uri = $_SERVER['PATH_INFO'];
	}
	else
	{
		// REQUEST_URI and PHP_SELF include the docroot and index

		if (isset($_SERVER['REQUEST_URI']))
		{
			// REQUEST_URI includes the query string, remove it
			$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

			// Decode the request URI
			$uri = rawurldecode($uri);
		}
		elseif (isset($_SERVER['PHP_SELF']))
		{
			$uri = $_SERVER['PHP_SELF'];
		}
		elseif (isset($_SERVER['REDIRECT_URL']))
		{
			$uri = $_SERVER['REDIRECT_URL'];
		}
		else
		{
			// If you ever see this error, please report an issue at http://dev.kohanaphp.com/projects/kohana3/issues
			// along with any relevant information about your web server setup. Thanks!
			throw new Kohana_Exception('Unable to detect the URI using PATH_INFO, REQUEST_URI, PHP_SELF or REDIRECT_URL');
		}

		// Get the path from the base URL, including the index file
		$base_url = parse_url(Kohana::$base_url, PHP_URL_PATH);

		if (strpos($uri, $base_url) === 0)
		{
			// Remove the base URL from the URI
			$uri = (string) substr($uri, strlen($base_url));
		}

		if (Kohana::$index_file AND strpos($uri, Kohana::$index_file) === 0)
		{
			// Remove the index file from the URI
			$uri = (string) substr($uri, strlen(Kohana::$index_file));
		}
	}

	return $uri;
}

public execute( )
Kohana_Request

Source Code
public function execute()
{
	// Create the class prefix
	$prefix = 'controller_';

	if ($this->directory)
	{
		// Add the directory name to the class prefix
		$prefix .= str_replace(array('\\', '/'), '_', trim($this->directory, '/')).'_';
	}

	if (Kohana::$profiling)
	{
		// Set the benchmark name
		$benchmark = '"'.$this->uri.'"';

		if ($this !== Request::$instance AND Request::$current)
		{
			// Add the parent request uri
			$benchmark .= ' « "'.Request::$current->uri.'"';
		}

		// Start benchmarking
		$benchmark = Profiler::start('Requests', $benchmark);
	}

	// Store the currently active request
	$previous = Request::$current;

	// Change the current request to this request
	Request::$current = $this;

	try
	{
		// Load the controller using reflection
		$class = new ReflectionClass($prefix.$this->controller);

		if ($class->isAbstract())
		{
			throw new Kohana_Exception('Cannot create instances of abstract :controller',
				array(':controller' => $prefix.$this->controller));
		}

		// Create a new instance of the controller
		$controller = $class->newInstance($this);

		// Execute the "before action" method
		$class->getMethod('before')->invoke($controller);

		// Determine the action to use
		$action = empty($this->action) ? Route::$default_action : $this->action;

		// Execute the main action with the parameters
		$class->getMethod('action_'.$action)->invokeArgs($controller, $this->_params);

		// Execute the "after action" method
		$class->getMethod('after')->invoke($controller);
	}
	catch (Exception $e)
	{
		// Restore the previous request
		Request::$current = $previous;

		if (isset($benchmark))
		{
			// Delete the benchmark, it is invalid
			Profiler::delete($benchmark);
		}

		if ($e instanceof ReflectionException)
		{
			// Reflection will throw exceptions for missing classes or actions
			$this->status = 404;
		}
		else
		{
			// All other exceptions are PHP/server errors
			$this->status = 500;
		}

		// Re-throw the exception
		throw $e;
	}

	// Restore the previous request
	Request::$current = $previous;

	if (isset($benchmark))
	{
		// Stop the benchmark
		Profiler::stop($benchmark);
	}

	return $this;
}

public static factory( )
Kohana_Request

Source Code
public static function factory($uri)
{
	return new Request($uri);
}

public generate_etag( )
Kohana_Request

Source Code
public function generate_etag()
{
    if ($this->response === NULL)
	{
		throw new Kohana_Request_Exception('No response yet associated with request - cannot auto generate resource ETag');
	}

	// Generate a unique hash for the response
	return '"'.sha1($this->response).'"';
}

public static instance( )
Kohana_Request

Source Code
public static function instance( & $uri = TRUE)
{
	if ( ! Request::$instance)
	{
		if (Kohana::$is_cli)
		{
			// Default protocol for command line is cli://
			Request::$protocol = 'cli';

			// Get the command line options
			$options = CLI::options('uri', 'method', 'get', 'post');

			if (isset($options['uri']))
			{
				// Use the specified URI
				$uri = $options['uri'];
			}

			if (isset($options['method']))
			{
				// Use the specified method
				Request::$method = strtoupper($options['method']);
			}

			if (isset($options['get']))
			{
				// Overload the global GET data
				parse_str($options['get'], $_GET);
			}

			if (isset($options['post']))
			{
				// Overload the global POST data
				parse_str($options['post'], $_POST);
			}
		}
		else
		{
			if (isset($_SERVER['REQUEST_METHOD']))
			{
				// Use the server request method
				Request::$method = $_SERVER['REQUEST_METHOD'];
			}

			if ( ! empty($_SERVER['HTTPS']) AND filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN))
			{
				// This request is secure
				Request::$protocol = 'https';
			}

			if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
			{
				// This request is an AJAX request
				Request::$is_ajax = TRUE;
			}

			if (isset($_SERVER['HTTP_REFERER']))
			{
				// There is a referrer for this request
				Request::$referrer = $_SERVER['HTTP_REFERER'];
			}

			if (isset($_SERVER['HTTP_USER_AGENT']))
			{
				// Set the client user agent
				Request::$user_agent = $_SERVER['HTTP_USER_AGENT'];
			}

			if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
			{
				// Use the forwarded IP address, typically set when the
				// client is using a proxy server.
				Request::$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
			}
			elseif (isset($_SERVER['HTTP_CLIENT_IP']))
			{
				// Use the forwarded IP address, typically set when the
				// client is using a proxy server.
				Request::$client_ip = $_SERVER['HTTP_CLIENT_IP'];
			}
			elseif (isset($_SERVER['REMOTE_ADDR']))
			{
				// The remote IP address
				Request::$client_ip = $_SERVER['REMOTE_ADDR'];
			}

			if (Request::$method !== 'GET' AND Request::$method !== 'POST')
			{
				// Methods besides GET and POST do not properly parse the form-encoded
				// query string into the $_POST array, so we overload it manually.
				parse_str(file_get_contents('php://input'), $_POST);
			}

			if ($uri === TRUE)
			{
				$uri = Request::detect_uri();
			}
		}

		// Reduce multiple slashes to a single slash
		$uri = preg_replace('#//+#', '/', $uri);

		// Remove all dot-paths from the URI, they are not valid
		$uri = preg_replace('#\.[\s./]*/#', '', $uri);

		// Create the instance singleton
		Request::$instance = Request::$current = new Request($uri);

		// Add the default Content-Type header
		Request::$instance->headers['Content-Type'] = 'text/html; charset='.Kohana::$charset;
	}

	return Request::$instance;
}

public param( )
Kohana_Request

Source Code
public function param($key = NULL, $default = NULL)
{
	if ($key === NULL)
	{
		// Return the full array
		return $this->_params;
	}

	return isset($this->_params[$key]) ? $this->_params[$key] : $default;
}

public redirect( )
Kohana_Request

Source Code
public function redirect($url = '', $code = 302)
{
	if (strpos($url, '://') === FALSE)
	{
		// Make the URI into a URL
		$url = URL::site($url, TRUE);
	}

	// Set the response status
	$this->status = $code;

	// Set the location header
	$this->headers['Location'] = $url;

	// Send headers
	$this->send_headers();

	// Stop execution
	exit;
}

public send_file( )
Kohana_Request

Source Code
public function send_file($filename, $download = NULL, array $options = NULL)
{
	if ( ! empty($options['mime_type']))
	{
		// The mime-type has been manually set
		$mime = $options['mime_type'];
	}

	if ($filename === TRUE)
	{
		if (empty($download))
		{
			throw new Kohana_Exception('Download name must be provided for streaming files');
		}

		// Temporary files will automatically be deleted
		$options['delete'] = FALSE;

		if ( ! isset($mime))
		{
			// Guess the mime using the file extension
			$mime = File::mime_by_ext(strtolower(pathinfo($download, PATHINFO_EXTENSION)));
		}

		// Force the data to be rendered if
		$file_data = (string) $this->response;

		// Get the content size
		$size = strlen($file_data);

		// Create a temporary file to hold the current response
		$file = tmpfile();

		// Write the current response into the file
		fwrite($file, $file_data);

		// File data is no longer needed
		unset($file_data);
	}
	else
	{
		// Get the complete file path
		$filename = realpath($filename);

		if (empty($download))
		{
			// Use the file name as the download file name
			$download = pathinfo($filename, PATHINFO_BASENAME);
		}

		// Get the file size
		$size = filesize($filename);

		if ( ! isset($mime))
		{
			// Get the mime type
			$mime = File::mime($filename);
		}

		// Open the file for reading
		$file = fopen($filename, 'rb');
	}

	if ( ! is_resource($file))
	{
		throw new Kohana_Exception('Could not read file to send: :file', array(
			':file' => $download,
		));
	}

	// Inline or download?
	$disposition = empty($options['inline']) ? 'attachment' : 'inline';

	// Calculate byte range to download.
	list($start, $end) = $this->_calculate_byte_range($size);

	if ( ! empty($options['resumable']))
	{
		if ($start > 0 OR $end < ($size - 1))
		{
			// Partial Content
			$this->status = 206;
		}

		// Range of bytes being sent
		$this->headers['Content-Range'] = 'bytes '.$start.'-'.$end.'/'.$size;
		$this->headers['Accept-Ranges'] = 'bytes';
	}

	// Set the headers for a download
	$this->headers['Content-Disposition'] = $disposition.'; filename="'.$download.'"';
	$this->headers['Content-Type']        = $mime;
	$this->headers['Content-Length']      = ($end - $start) + 1;

	if (Request::user_agent('browser') === 'Internet Explorer')
	{
		// Naturally, IE does not act like a real browser...
		if (Request::$protocol === 'https')
		{
			// http://support.microsoft.com/kb/316431
			$this->headers['Pragma'] = $this->headers['Cache-Control'] = 'public';
		}

		if (version_compare(Request::user_agent('version'), '8.0', '>='))
		{
			// http://ajaxian.com/archives/ie-8-security
			$this->headers['X-Content-Type-Options'] = 'nosniff';
		}
	}

	// Send all headers now
	$this->send_headers();

	while (ob_get_level())
	{
		// Flush all output buffers
		ob_end_flush();
	}

	// Manually stop execution
	ignore_user_abort(TRUE);

	if ( ! Kohana::$safe_mode)
	{
		// Keep the script running forever
		set_time_limit(0);
	}

	// Send data in 16kb blocks
	$block = 1024 * 16;

	fseek($file, $start);

	while ( ! feof($file) AND ($pos = ftell($file)) <= $end)
	{
		if (connection_aborted())
			break;

		if ($pos + $block > $end)
		{
			// Don't read past the buffer.
			$block = $end - $pos + 1;
		}

		// Output a block of the file
		echo fread($file, $block);

		// Send the data now
		flush();
	}

	// Close the file
	fclose($file);

	if ( ! empty($options['delete']))
	{
		try
		{
			// Attempt to remove the file
			unlink($filename);
		}
		catch (Exception $e)
		{
			// Create a text version of the exception
			$error = Kohana::exception_text($e);

			if (is_object(Kohana::$log))
			{
				// Add this exception to the log
				Kohana::$log->add(Kohana::ERROR, $error);

				// Make sure the logs are written
				Kohana::$log->write();
			}

			// Do NOT display the exception, it will corrupt the output!
		}
	}

	// Stop execution
	exit;
}

public send_headers( )
Kohana_Request

Source Code
public function send_headers()
{
	if ( ! headers_sent())
	{
		if (isset($_SERVER['SERVER_PROTOCOL']))
		{
			// Use the default server protocol
			$protocol = $_SERVER['SERVER_PROTOCOL'];
		}
		else
		{
			// Default to using newer protocol
			$protocol = 'HTTP/1.1';
		}

		// HTTP status line
		header($protocol.' '.$this->status.' '.Request::$messages[$this->status]);

		foreach ($this->headers as $name => $value)
		{
			if (is_string($name))
			{
				// Combine the name and value to make a raw header
				$value = "{$name}: {$value}";
			}

			// Send the raw header
			header($value, TRUE);
		}
	}

	return $this;
}

public uri( )
Kohana_Request

Source Code
public function uri(array $params = NULL)
{
	if ( ! isset($params['directory']))
	{
		// Add the current directory
		$params['directory'] = $this->directory;
	}

	if ( ! isset($params['controller']))
	{
		// Add the current controller
		$params['controller'] = $this->controller;
	}

	if ( ! isset($params['action']))
	{
		// Add the current action
		$params['action'] = $this->action;
	}

	// Add the current parameters
	$params += $this->_params;

	return $this->route->uri($params);
}

public url( )
Kohana_Request

Source Code
public function url(array $params = NULL, $protocol = NULL)
{
	// Create a URI with the current route and convert it to a URL
	return URL::site($this->uri($params), $protocol);
}

public static user_agent( )
Kohana_Request

Source Code
public static function user_agent($value)
{
	if (is_array($value))
	{
		$agent = array();
		foreach ($value as $v)
		{
			// Add each key to the set
			$agent[$v] = Request::user_agent($v);
		}

		return $agent;
	}

	static $info;

	if (isset($info[$value]))
	{
		// This value has already been found
		return $info[$value];
	}

	if ($value === 'browser' OR $value == 'version')
	{
		// Load browsers
		$browsers = Kohana::config('user_agents')->browser;

		foreach ($browsers as $search => $name)
		{
			if (stripos(Request::$user_agent, $search) !== FALSE)
			{
				// Set the browser name
				$info['browser'] = $name;

				if (preg_match('#'.preg_quote($search).'[^0-9.]*+([0-9.][0-9.a-z]*)#i', Request::$user_agent, $matches))
				{
					// Set the version number
					$info['version'] = $matches[1];
				}
				else
				{
					// No version number found
					$info['version'] = FALSE;
				}

				return $info[$value];
			}
		}
	}
	else
	{
		// Load the search group for this type
		$group = Kohana::config('user_agents')->$value;

		foreach ($group as $search => $name)
		{
			if (stripos(Request::$user_agent, $search) !== FALSE)
			{
				// Set the value name
				return $info[$value] = $name;
			}
		}
	}

	// The value requested could not be found
	return $info[$value] = FALSE;
}