Request Client for internal execution
Class declared in SYSPATH/classes/kohana/request/client/internal.php on line 12.
boolean
$_allow_private_cachelink to thisDefines whether this client should cache private
cache directives
Cache
$_cachelink to thisCaching library for request caching
array
$_previous_environmentlink to thisint
$_request_timelink to thisThe timestamp of the request
int
$_response_timelink to thisThe timestamp of the response
Processes the request, executing the controller action that handles this request, determined by the Route.
By default, the output from the controller is captured and returned, and no headers are sent.
$request
->execute();
will be removed in 3.2
Request
$request
required - $requestResponse
public
function
execute(Request
$request
)
{
// Check for cache existance
if
(
$this
->_cache
instanceof
Cache AND (
$response
=
$this
->cache_response(
$request
))
instanceof
Response)
return
$response
;
// Create the class prefix
$prefix
=
'controller_'
;
// Directory
$directory
=
$request
->directory();
// Controller
$controller
=
$request
->controller();
if
(
$directory
)
{
// Add the directory name to the class prefix
$prefix
.=
str_replace
(
array
(
'\\'
,
'/'
),
'_'
, trim(
$directory
,
'/'
)).
'_'
;
}
if
(Kohana::
$profiling
)
{
// Set the benchmark name
$benchmark
=
'"'
.
$request
->uri().
'"'
;
if
(
$request
!== Request::
$initial
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
=
$request
;
// Is this the initial request
$initial_request
= (
$request
=== Request::
$initial
);
try
{
// Initiate response time
$this
->_response_time = time();
if
( !
class_exists
(
$prefix
.
$controller
))
{
throw
new
HTTP_Exception_404(
'The requested URL :uri was not found on this server.'
,
array
(
':uri'
=>
$request
->uri()));
}
// Load the controller using reflection
$class
=
new
ReflectionClass(
$prefix
.
$controller
);
if
(
$class
->isAbstract())
{
throw
new
Kohana_Exception(
'Cannot create instances of abstract :controller'
,
array
(
':controller'
=>
$prefix
.
$controller
));
}
// Create a new instance of the controller
$controller
=
$class
->newInstance(
$request
,
$request
->response() ?
$request
->response() :
$request
->create_response());
$class
->getMethod(
'before'
)->invoke(
$controller
);
// Determine the action to use
$action
=
$request
->action();
$params
=
$request
->param();
// If the action doesn't exist, it's a 404
if
( !
$class
->hasMethod(
'action_'
.
$action
))
{
throw
new
HTTP_Exception_404(
'The requested URL :uri was not found on this server.'
,
array
(
':uri'
=>
$request
->uri()));
}
$method
=
$class
->getMethod(
'action_'
.
$action
);
/**
* Execute the main action with the parameters
*
* @deprecated $params passing is deprecated since version 3.1
* will be removed in 3.2.
*/
$method
->invokeArgs(
$controller
,
$params
);
// Execute the "after action" method
$class
->getMethod(
'after'
)->invoke(
$controller
);
// Stop response time
$this
->_response_time = (time() -
$this
->_response_time);
// Add the default Content-Type header to initial request if not present
if
(
$initial_request
AND !
$request
->headers(
'content-type'
))
{
$request
->headers(
'content-type'
, Kohana::
$content_type
.
'; charset='
.Kohana::
$charset
);
}
}
catch
(Exception
$e
)
{
// Restore the previous request
if
(
$previous
instanceof
Request)
{
Request::
$current
=
$previous
;
}
if
(isset(
$benchmark
))
{
// Delete the benchmark, it is invalid
Profiler::
delete
(
$benchmark
);
}
// Re-throw the exception
throw
$e
;
}
// Restore the previous request
Request::
$current
=
$previous
;
if
(isset(
$benchmark
))
{
// Stop the benchmark
Profiler::stop(
$benchmark
);
}
// Cache the response if cache is available
if
(
$this
->_cache
instanceof
Cache)
{
$this
->cache_response(
$request
,
$request
->response());
}
// Return the response
return
$request
->response();
}
Creates a new Request_Client
object,
allows for dependency injection.
array
$params
= array(0) - Params
public
function
__construct(
array
$params
=
array
())
{
if
(
$params
)
{
foreach
(
$params
as
$key
=>
$value
)
{
if
(method_exists(
$this
,
$key
))
{
if
(property_exists(
$this
,
$key
) OR property_exists(
$this
,
'_'
.
$key
))
{
$method
= trim(
$key
,
'_'
);
$this
->
$method
(
$value
);
}
}
}
}
}
Gets or sets the Request_Client::allow_private_cache setting.
If set to TRUE
, the client will also cache cache-control directives
that have the private
setting.
boolean
$setting
= NULL - Allow caching of privately marked responsesboolean
[Request_Client]
public
function
allow_private_cache(
$setting
= NULL)
{
if
(
$setting
=== NULL)
return
$this
->_allow_private_cache;
$this
->_allow_private_cache = (bool)
$setting
;
return
$this
;
}
Getter and setter for the internal caching engine, used to cache responses if available and valid.
Kohana_Cache
$cache
= NULL - Cache engine to use for cachingKohana_Cache
Kohana_Request_Client
public
function
cache(Cache
$cache
= NULL)
{
if
(
$cache
=== NULL)
return
$this
->_cache;
$this
->_cache =
$cache
;
return
$this
;
}
Calculates the total Time To Live based on the specification RFC 2616 cache lifetime rules.
Response
$response
required - Response to evaluatemixed
- TTL value or false if the response should not be cached
public
function
cache_lifetime(Response
$response
)
{
// Get out of here if this cannot be cached
if
( !
$this
->set_cache(
$response
))
return
FALSE;
// Calculate apparent age
if
(
$date
=
$response
->headers(
'date'
))
{
$apparent_age
= max(0,
$this
->_response_time -
strtotime
( (string)
$date
));
}
else
{
$apparent_age
= max(0,
$this
->_response_time);
}
// Calculate corrected received age
if
(
$age
=
$response
->headers(
'age'
))
{
$corrected_received_age
= max(
$apparent_age
,
intval
( (string)
$age
));
}
else
{
$corrected_received_age
=
$apparent_age
;
}
// Corrected initial age
$corrected_initial_age
=
$corrected_received_age
+
$this
->request_execution_time();
// Resident time
$resident_time
= time() -
$this
->_response_time;
// Current age
$current_age
=
$corrected_initial_age
+
$resident_time
;
// Prepare the cache freshness lifetime
$ttl
= NULL;
// Cache control overrides
if
(
$cache_control
=
$response
->headers(
'cache-control'
))
{
// Parse the cache control header
$cache_control
= Response::parse_cache_control( (string)
$cache_control
);
if
(isset(
$cache_control
[
'max-age'
]))
{
$ttl
= (int)
$cache_control
[
'max-age'
];
}
if
(isset(
$cache_control
[
's-maxage'
]) AND isset(
$cache_control
[
'private'
]) AND
$this
->_allow_private_cache)
{
$ttl
= (int)
$cache_control
[
's-maxage'
];
}
if
(isset(
$cache_control
[
'max-stale'
]) AND ! isset(
$cache_control
[
'must-revalidate'
]))
{
$ttl
=
$current_age
+ (int)
$cache_control
[
'max-stale'
];
}
}
// If we have a TTL at this point, return
if
(
$ttl
!== NULL)
return
$ttl
;
if
(
$expires
=
$response
->headers(
'expires'
))
return
strtotime
( (string)
$expires
) -
$current_age
;
return
FALSE;
}
Caches a Response using the supplied Cache and the key generated by Request_Client::_create_cache_key.
If not response is supplied, the cache will be checked for an existing one that is available.
Request
$request
required - The requestResponse
$response
= NULL - Responsemixed
public
function
cache_response(Request
$request
, Response
$response
= NULL)
{
if
( !
$this
->_cache
instanceof
Cache)
return
FALSE;
// Check for Pragma: no-cache
if
(
$pragma
=
$request
->headers(
'pragma'
))
{
if
(
$pragma
instanceof
HTTP_Header_Value
and
$pragma
->key ==
'no-cache'
)
return
FALSE;
elseif
(
is_array
(
$pragma
)
and
isset(
$pragma
[
'no-cache'
]))
return
FALSE;
}
if
( !
$response
)
{
$response
=
$this
->_cache->get(
$this
->create_cache_key(
$request
));
return
(
$response
!== NULL) ?
$response
: FALSE;
}
else
{
if
((
$ttl
=
$this
->cache_lifetime(
$response
)) === FALSE)
return
FALSE;
return
$this
->_cache->set(
$this
->create_cache_key(
$request
),
$response
,
$ttl
);
}
}
Creates a cache key for the request to use for caching Kohana_Response returned by Request::execute.
Request
$request
required - Requeststring
boolean
public
function
create_cache_key(Request
$request
)
{
return
sha1(
$request
->url());
}
Invalidate a cached response for the Request supplied. This has the effect of deleting the response from the Cache entry.
Request
$request
required - Response to remove from cachevoid
public
function
invalidate_cache(Request
$request
)
{
if
( !
$this
->_cache
instanceof
Cache)
return
;
$this
->_cache->
delete
(
$this
->_create_cache_key(
$request
));
return
;
}
Returns the duration of the last request execution.
Either returns the time of completed requests or
FALSE
if the request hasn't finished executing, or
is yet to be run.
mixed
public
function
request_execution_time()
{
if
(
$this
->_request_time === NULL OR
$this
->_response_time === NULL)
return
FALSE;
return
$this
->_response_time -
$this
->_request_time;
}
Controls whether the response can be cached. Uses HTTP protocol to determine whether the response can be cached.
Response
$response
required - The Responseboolean
public
function
set_cache(Response
$response
)
{
$headers
= (
array
)
$response
->headers();
if
(
$cache_control
= arr::get(
$headers
,
'cache-control'
))
{
// Parse the cache control
$cache_control
= Response::parse_cache_control( (string)
$cache_control
);
// If the no-cache or no-store directive is set, return
if
(
array_intersect_key
(
$cache_control
,
array
(
'no-cache'
=> NULL,
'no-store'
=> NULL)))
return
FALSE;
// Get the directives
$directives
=
array_keys
(
$cache_control
);
// Check for private cache and get out of here if invalid
if
( !
$this
->_allow_private_cache
and
in_array(
'private'
,
$directives
))
{
if
( ! isset(
$cache_control
[
's-maxage'
]))
return
FALSE;
// If there is a s-maxage directive we can use that
$cache_control
[
'max-age'
] =
$cache_control
[
's-maxage'
];
}
// Check that max-age has been set and if it is valid for caching
if
(isset(
$cache_control
[
'max-age'
])
and
(int)
$cache_control
[
'max-age'
] < 1)
return
FALSE;
}
if
(
$expires
= arr::get(
$headers
,
'expires'
)
and
! isset(
$cache_control
[
'max-age'
]))
{
// Can't cache things that have expired already
if
(
strtotime
( (string)
$expires
) <= time())
return
FALSE;
}
return
TRUE;
}