public function beforeDispatch(Event $event) { $event->stopPropagation(); $response = new Response(['body' => $this->config('message')]); $response->httpCodes([429 => 'Too Many Requests']); $response->statusCode(429); return $response; }
/** * @author Gaetan SENELLE * @return Response */ public function render() { $response = new Response(); $exception = $this->error; $code = $this->_code($exception); $message = $this->_message($exception, $code); $url = $this->controller->request->here(); $isDebug = Configure::read('debug'); $response->statusCode($code); if (method_exists($exception, 'responseHeader')) { $this->controller->response->header($exception->responseHeader()); } $classname = get_class($exception); if (preg_match('@\\\\([\\w]+)$@', $classname, $matches)) { $classname = $matches[1]; } else { $classname = null; } if (!$isDebug && !$exception instanceof ApiException && !$exception instanceof HttpException) { $classname = null; } $data = ['exception' => ['type' => $classname, 'message' => $message, 'url' => h($url), 'code' => $code], 'success' => false]; $response->body(json_encode($data)); $response->type('json'); return $response; }
/** * Convert a CakePHP response into a PSR7 one. * * @param CakeResponse $response The CakePHP response to convert * @return PsrResponse $response The equivalent PSR7 response. */ public static function toPsr(CakeResponse $response) { $status = $response->statusCode(); $headers = $response->header(); if (!isset($headers['Content-Type'])) { $headers['Content-Type'] = $response->type(); } $body = $response->body(); $stream = 'php://memory'; if (is_string($body)) { $stream = new Stream('php://memory', 'wb'); $stream->write($response->body()); } if (is_callable($body)) { $stream = new CallbackStream($body); } // This is horrible, but CakePHP doesn't have a getFile() method just yet. $fileProp = new \ReflectionProperty($response, '_file'); $fileProp->setAccessible(true); $file = $fileProp->getValue($response); if ($file) { $stream = new Stream($file->path, 'rb'); } return new DiactorosResponse($stream, $status, $headers); }
/** * Filters the cake response to the BrowserKit one. * * @param \Cake\Network\Response $response Cake response. * @return \Symfony\Component\BrowserKit\Response BrowserKit response. */ protected function filterResponse($response) { $this->cake['response'] = $response; foreach ($response->cookie() as $cookie) { $this->getCookieJar()->set(new Cookie($cookie['name'], $cookie['value'], $cookie['expire'], $cookie['path'], $cookie['domain'], $cookie['secure'], $cookie['httpOnly'])); } $response->sendHeaders(); return new BrowserKitResponse($response->body(), $response->statusCode(), $response->header()); }
/** * @param \Cake\Network\Request $request Request to get authentication information from. * @param \Cake\Network\Response $response A response object that can have headers added. * @return bool|\Cake\Network\Response */ public function unauthenticated(Request $request, Response $response) { if ($this->_config['continue']) { return false; } if (isset($this->_exception)) { $response->statusCode($this->_exception->httpStatusCode); $response->header($this->_exception->getHttpHeaders()); $response->body(json_encode(['error' => $this->_exception->errorType, 'message' => $this->_exception->getMessage()])); return $response; } $message = __d('authenticate', 'You are not authenticated.'); throw new BadRequestException($message); }
/** * Main functionality to trigger maintenance mode. * Will automatically set the appropriate headers. * * Tip: Check for non CLI first * * if (php_sapi_name() !== 'cli') { * App::uses('MaintenanceLib', 'Setup.Lib'); * $Maintenance = new MaintenanceLib(); * $Maintenance->checkMaintenance(); * } * * @param string|null $ipAddress * @param bool $exit If Response should be sent and exited. * @return void * @deprecated Use Maintenance DispatcherFilter */ public function checkMaintenance($ipAddress = null, $exit = true) { if ($ipAddress === null) { $ipAddress = env('REMOTE_ADDRESS'); } if (!$this->isMaintenanceMode($ipAddress)) { return; } $Response = new Response(); $Response->statusCode(503); $Response->header('Retry-After', DAY); $body = __d('setup', 'Maintenance work'); $template = APP . 'Template' . DS . 'Error' . DS . $this->template; if (file_exists($template)) { $body = file_get_contents($template); } $Response->body($body); if ($exit) { $Response->send(); exit; } }
/** * @param \Cake\Network\Request $request Request to get authentication information from. * @param \Cake\Network\Response $response A response object that can have headers added. * @return bool|\Cake\Network\Response */ public function unauthenticated(Request $request, Response $response) { if ($this->_config['continue']) { return null; } if (isset($this->_exception)) { $response->statusCode($this->_exception->httpStatusCode); //add : to http code for cakephp (header method in Network/Response expects header separated with colon notation) $headers = $this->_exception->getHttpHeaders(); $code = (string) $this->_exception->httpStatusCode; $headers = array_map(function ($header) use($code) { $pos = strpos($header, $code); if ($pos !== false) { return substr($header, 0, $pos + strlen($code)) . ':' . substr($header, $pos + strlen($code) + 1); } return $header; }, $headers); $response->header($headers); $response->body(json_encode(['error' => $this->_exception->errorType, 'message' => $this->_exception->getMessage()])); return $response; } $message = __d('authenticate', 'You are not authenticated.'); throw new BadRequestException($message); }
/** * Handles unauthenticated access attempt. First the `unauthenticated()` method * of the last authenticator in the chain will be called. The authenticator can * handle sending response or redirection as appropriate and return `true` to * indicate no further action is necessary. If authenticator returns null this * method redirects user to login action. If it's an AJAX request and config * `ajaxLogin` is specified that element is rendered else a 403 HTTP status code * is returned. * * @param \Cake\Controller\Controller $controller A reference to the controller object. * @return \Cake\Network\Response|null Null if current action is login action * else response object returned by authenticate object or Controller::redirect(). */ protected function _unauthenticated(Controller $controller) { if (empty($this->_authenticateObjects)) { $this->constructAuthenticate(); } $auth = end($this->_authenticateObjects); $result = $auth->unauthenticated($this->request, $this->response); if ($result !== null) { return $result; } if (!$this->storage()->redirectUrl()) { $this->storage()->redirectUrl($this->request->here(false)); } if (!$controller->request->is('ajax')) { $this->flash($this->_config['authError']); $this->storage()->redirectUrl($controller->request->here(false)); return $controller->redirect($this->_config['loginAction']); } if (!empty($this->_config['ajaxLogin'])) { $controller->viewBuilder()->templatePath('Element'); $response = $controller->render($this->_config['ajaxLogin'], $this->RequestHandler->ajaxLayout); $response->statusCode(403); return $response; } $this->response->statusCode(403); return $this->response; }
/** * Helper method for status assertions. * * @param int $min Min status code. * @param int $max Max status code. * @param string $message The error message. * @return void */ protected function _assertStatus($min, $max, $message) { if (!$this->_response) { $this->fail('No response set, cannot assert status code.'); } $status = $this->_response->statusCode(); $this->assertGreaterThanOrEqual($min, $status, $message); $this->assertLessThanOrEqual($max, $status, $message); }
/** * beforeDispatch. * * @param Cake\Event\Event $event Event instance * @return mixed Cake\Network\Response when limit is reached, void otherwise */ public function beforeDispatch(Event $event) { $this->_setIdentifier($event->data['request']); $this->_initCache(); $this->_count = $this->_touch($event->data['request']); // client has not exceeded rate limit if ($this->_count <= $this->config('limit')) { $this->_setHeaders($event->data['response']); return; } // client has reached rate limit $event->stopPropagation(); $response = new Response(['body' => $this->config('message')]); $response->httpCodes([429 => 'Too Many Requests']); $response->statusCode(429); return $response; }
/** * Tests the statusCode method * * @expectedException \InvalidArgumentException * @return void */ public function testStatusCode() { $response = new Response(); $this->assertEquals(200, $response->statusCode()); $response->statusCode(404); $this->assertEquals(404, $response->statusCode()); $this->assertEquals(500, $response->statusCode(500)); //Throws exception $response->statusCode(1001); }
/** * Handles (fakes) redirects for AJAX requests using requestAction() * * @param Event $event The Controller.beforeRedirect event. * @param string|array $url A string or array containing the redirect location * @param \Cake\Network\Response $response The response object. * @return void|\Cake\Network\Response The response object if the redirect is caught. */ public function beforeRedirect(Event $event, $url, Response $response) { $request = $this->request; if (!$request->is('ajax')) { return; } if (empty($url)) { return; } if (is_array($url)) { $url = Router::url($url + ['_base' => false]); } $controller = $event->subject(); $response->body($controller->requestAction($url, ['return', 'bare' => false, 'environment' => ['REQUEST_METHOD' => 'GET']])); $response->statusCode(200); return $response; }
/** * Handles unauthenticated access attempt. First the `unauthenticated()` method * of the last authenticator in the chain will be called. The authenticator can * handle sending response or redirection as appropriate and return `true` to * indicate no further action is necessary. If authenticator returns null this * method redirects user to login action. If it's an AJAX request and config * `ajaxLogin` is specified that element is rendered else a 403 HTTP status code * is returned. * * @param \Cake\Controller\Controller $controller A reference to the controller object. * @return void|\Cake\Network\Response Null if current action is login action * else response object returned by authenticate object or Controller::redirect(). */ protected function _unauthenticated(Controller $controller) { if (empty($this->_authenticateObjects)) { $this->constructAuthenticate(); } $auth = end($this->_authenticateObjects); $result = $auth->unauthenticated($this->request, $this->response); if ($result !== null) { return $result; } if ($this->_isLoginAction($controller)) { if (empty($controller->request->data) && !$this->session->check('Auth.redirect') && $this->request->env('HTTP_REFERER')) { $this->session->write('Auth.redirect', $controller->referer(null, true)); } return; } if (!$controller->request->is('ajax')) { $this->flash($this->_config['authError']); $this->session->write('Auth.redirect', $controller->request->here(false)); return $controller->redirect($this->_config['loginAction']); } if (!empty($this->_config['ajaxLogin'])) { $controller->viewPath = 'Element'; $response = $controller->render($this->_config['ajaxLogin'], $this->RequestHandler->ajaxLayout); $response->statusCode(403); return $response; } $this->response->statusCode(403); return $this->response; }
/** * Add in the Content-Type header if necessary. * * @param array $headers The headers to update * @param \Cake\Network\Response $response The CakePHP response to convert * @return array The updated headers. */ protected static function setContentType($headers, $response) { if (isset($headers['Content-Type'])) { return $headers; } if (in_array($response->statusCode(), [204, 304])) { return $headers; } $whitelist = ['application/javascript', 'application/json', 'application/xml', 'application/rss+xml']; $type = $response->type(); $charset = $response->charset(); $hasCharset = false; if ($charset && (strpos($type, 'text/') === 0 || in_array($type, $whitelist))) { $hasCharset = true; } $value = $type; if ($hasCharset) { $value = "{$type}; charset={$charset}"; } $headers['Content-Type'] = $value; return $headers; }
/** * Handles (fakes) redirects for AJAX requests using requestAction() * * @param Event $event The Controller.beforeRedirect event. * @param string|array $url A string or array containing the redirect location * @param \Cake\Network\Response $response The response object. * @return \Cake\Network\Response|null The response object if the redirect is caught. */ public function beforeRedirect(Event $event, $url, Response $response) { $request = $this->request; if (!$request->is('ajax')) { return null; } if (empty($url)) { return null; } if (is_array($url)) { $url = Router::url($url + ['_base' => false]); } $query = []; if (strpos($url, '?') !== false) { list($url, $querystr) = explode('?', $url, 2); parse_str($querystr, $query); } $controller = $event->subject(); $response->body($controller->requestAction($url, ['return', 'bare' => false, 'environment' => ['REQUEST_METHOD' => 'GET'], 'query' => $query])); $response->statusCode(200); return $response; }
/** * Generates the unauthorized response * @param \Cake\Network\Response $response A response object. * @return \Cake\Network\Response */ private function unauthorizedResponse($response) { $response->statusCode(403); $response->body(json_encode((object) ['message' => 'Error al verificar el token de autorización, no tiene permiso para acceder a la aplicación', 'code' => 403])); return $response; }
public function beforeRedirect(Event $event, $url, Response $response) { // $logged_in = is_int($this->Controller->Auth->user('id')); $login_action = false; if (is_string($url)) { if (stripos($url, 'login') !== false) { $login_action = true; } } elseif (is_array($url)) { if ($url['action'] == 'login') { $login_action = true; } } if ($this->request->is('service') && !$logged_in && $login_action) { $this->data = [self::SUCCESS_KEY => false, self::ENABLE_KEY => true, self::CODE_KEY => 401, self::MESSAGE_KEY => __('You are not logged in!')]; $this->Controller->render(); $response->statusCode(201); $response->send(); $response->stop(); if (session_id()) { session_write_close(); } } }
/** * Parses a string URL into an array. Parsed URLs will result in an automatic * redirection * * @param string $url The URL to parse * @return bool False on failure */ public function parse($url) { $params = parent::parse($url); if (!$params) { return false; } if (!$this->response) { $this->response = new Response(); } $redirect = $this->redirect; if (count($this->redirect) === 1 && !isset($this->redirect['controller'])) { $redirect = $this->redirect[0]; } if (isset($this->options['persist']) && is_array($redirect)) { $redirect += ['pass' => $params['pass'], 'url' => []]; if (is_array($this->options['persist'])) { foreach ($this->options['persist'] as $elem) { if (isset($params[$elem])) { $redirect[$elem] = $params[$elem]; } } } $redirect = Router::reverse($redirect); } $status = 301; if (isset($this->options['status']) && ($this->options['status'] >= 300 && $this->options['status'] < 400)) { $status = $this->options['status']; } $this->response->header(['Location' => Router::url($redirect, true)]); $this->response->statusCode($status); $this->response->send(); $this->response->stop(); }
/** * Called before Controller::redirect(). Allows you to replace the URL that will * be redirected to with a new URL. * * @param \Cake\Event\Event $event Event * @param string|array $url Either the string or URL array that is being redirected to. * @param \Cake\Network\Response $response * @return void */ public function beforeRedirect(Event $event, $url, Response $response) { if (!$this->respondAsAjax || !$this->_config['resolveRedirect']) { return; } $url = Router::url($url, true); $status = $response->statusCode(); $response->statusCode(200); $this->Controller->autoRender = true; $this->Controller->set('_redirect', compact('url', 'status')); $serializeKeys = ['_redirect']; if (!empty($this->Controller->viewVars['_serialize'])) { $serializeKeys = array_merge($serializeKeys, $this->Controller->viewVars['_serialize']); } $this->Controller->set('_serialize', $serializeKeys); $event->stopPropagation(); }