/** * The default handler for following redirects, triggered by the presence of * a Location header in the response. * * The client's follow property must be set TRUE and the HTTP response status * one of 201, 301, 302, 303 or 307 for the redirect to be followed. * * @param Request $request * @param Response $response * @param Request_Client $client */ public static function on_header_location(Request $request, Response $response, Request_Client $client) { // Do we need to follow a Location header ? if ($client->follow() and in_array($response->status(), array(201, 301, 302, 303, 307))) { // Figure out which method to use for the follow request switch ($response->status()) { default: case 301: case 307: $follow_method = $request->method(); break; case 201: case 303: $follow_method = Request::GET; break; case 302: // Cater for sites with broken HTTP redirect implementations if ($client->strict_redirect()) { $follow_method = $request->method(); } else { $follow_method = Request::GET; } break; } // Prepare the additional request, copying any follow_headers that were present on the original request $orig_headers = $request->headers()->getArrayCopy(); $follow_header_keys = array_intersect(array_keys($orig_headers), $client->follow_headers()); $follow_headers = \Arr::extract($orig_headers, $follow_header_keys); $follow_request = Request::factory($response->headers('Location'))->method($follow_method)->headers($follow_headers); if ($follow_method !== Request::GET) { $follow_request->body($request->body()); } return $follow_request; } return NULL; }
/** * Header callback for testing that arbitrary callback_params are available * to the callback. * * @param Request $request * @param Response $response * @param Request_Client $client */ public function callback_assert_params($request, $response, $client) { $this->assertEquals('foo', $client->callback_params('constructor_param')); $this->assertEquals('bar', $client->callback_params('setter_param')); $response->body('assertions_ran'); }
/** * Executes the supplied [Request] with the supplied [Request_Client]. * Before execution, the HTTP_Cache adapter checks the request type, * destructive requests such as `POST`, `PUT` and `DELETE` will bypass * cache completely and ensure the response is not cached. All other * Request methods will allow caching, if the rules are met. * * @param Request_Client $client client to execute with Cache-Control * @param Request $request request to execute with client * @return [Response] */ public function execute(Request_Client $client, Request $request, Response $response) { if (!$this->_cache instanceof Cache) { return $client->execute_request($request, $response); } // If this is a destructive request, by-pass cache completely if (in_array($request->method(), array(HTTP_Request::POST, HTTP_Request::PUT, HTTP_Request::DELETE))) { // Kill existing caches for this request $this->invalidate_cache($request); $response = $client->execute_request($request, $response); $cache_control = HTTP_Header::create_cache_control(array('no-cache', 'must-revalidate')); // Ensure client respects destructive action return $response->headers('cache-control', $cache_control); } // Create the cache key $cache_key = $this->create_cache_key($request, $this->_cache_key_callback); // Try and return cached version if (($cached_response = $this->cache_response($cache_key, $request)) instanceof Response) { return $cached_response; } // Start request time $this->_request_time = time(); // Execute the request with the Request client $response = $client->execute_request($request, $response); // Stop response time $this->_response_time = time() - $this->_request_time; // Cache the response $this->cache_response($cache_key, $request, $response); $response->headers(HTTP_Cache::CACHE_STATUS_KEY, HTTP_Cache::CACHE_STATUS_MISS); return $response; }
/** * Assigns the properties of the current Request_Client to another * Request_Client instance - used when setting up a subsequent request. * * @param Request_Client $client */ public function assign_client_properties(Request_Client $client) { $client->cache($this->cache()); $client->follow($this->follow()); $client->follow_headers($this->follow_headers()); $client->header_callbacks($this->header_callbacks()); $client->max_callback_depth($this->max_callback_depth()); $client->callback_params($this->callback_params()); }
public static function on_header_location(Request $request, Response $response, Request_Client $client) { if ($client->follow() and in_array($response->status(), array(201, 301, 302, 303, 307))) { switch ($response->status()) { default: case 301: case 307: $follow_method = $request->method(); break; case 201: case 303: $follow_method = Request::GET; break; case 302: if ($client->strict_redirect()) { $follow_method = $request->method(); } else { $follow_method = Request::GET; } break; } $orig_headers = $request->headers()->getArrayCopy(); $follow_header_keys = array_intersect(array_keys($orig_headers), $client->follow_headers()); $follow_headers = \Arr::extract($orig_headers, $follow_header_keys); $follow_request = Request::factory($response->headers("Location"))->method($follow_method)->headers($follow_headers); if ($follow_method !== Request::GET) { $follow_request->body($request->body()); } return $follow_request; } return NULL; }
/** * Processes the request, executing the controller action that handles this * request, determined by the [Route]. * * 1. Before the controller action is called, the [Controller::before] method * will be called. * 2. Next the controller action will be called. * 3. After the controller action is called, the [Controller::after] method * will be called. * * By default, the output from the controller is captured and returned, and * no headers are sent. * * Example: * ~~~ * $request->execute(); * ~~~ * * @return Response * * @throws Request_Exception * * @throws HTTP_Exception_404 * @uses [Kohana::$profiling] * @uses [Profiler] * @uses Gleez::block_ips * @uses Gleez::maintenance_mode */ public function execute() { if (Gleez::$installed) { // Deny access to blocked IP addresses Gleez::block_ips(); // Check Maintenance Mode Gleez::maintenance_mode(); } if (!$this->_external) { $processed = Request::process($this, $this->_routes); if ($processed) { // Store the matching route $this->_route = $processed['route']; $params = $processed['params']; // Is this route external? $this->_external = $this->_route->is_external(); if (isset($params['directory'])) { // Controllers are in a sub-directory $this->_directory = $params['directory']; } // Store the controller $this->_controller = $params['controller']; // Store the action $this->_action = isset($params['action']) ? $params['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; } } if (!$this->_route instanceof Route) { return HTTP_Exception::factory(404, 'Unable to find a route to match the URI: :uri', array(':uri' => $this->_uri))->request($this)->get_response(); } if (!$this->_client instanceof Request_Client) { throw new Request_Exception('Unable to execute :uri without a Kohana_Request_Client', array(':uri' => $this->_uri)); } return $this->_client->execute($this); }