### Single header
header('Location', 'http://example.com');
### Multiple headers
header(['Location' => 'http://example.com', 'X-Extra' => 'My header']);
### String header
header('WWW-Authenticate: Negotiate');
### Array of string headers
header(['WWW-Authenticate: Negotiate', 'Content-type: application/pdf']);
Multiple calls for setting the same header name will have the same effect as setting the header once
with the last value sent for it
header('WWW-Authenticate: Negotiate');
header('WWW-Authenticate: Not-Negotiate');
will have the same effect as only doing
header('WWW-Authenticate: Not-Negotiate');
public header ( string | array | null $header = null, string | array | null $value = null ) : array | ||
$header | string | array | null | An array of header strings or a single header string - an associative array of "header name" => "header value" is also accepted - an array of string headers is also accepted |
$value | string | array | null | The header value(s) |
Результат | array | List of headers to be sent |
/** * Apply the queued headers to the response. * * If the builder has no Origin, or if there are no allowed domains, * or if the allowed domains do not match the Origin header no headers will be applied. * * @return \Cake\Network\Response */ public function build() { if (empty($this->_origin)) { return $this->_response; } if (isset($this->_headers['Access-Control-Allow-Origin'])) { $this->_response->header($this->_headers); } return $this->_response; }
/** * Create the response. * * @param \League\Flysystem\FilesystemInterface $cache The cache file system. * @param string $path The cached file path. * * @return \Cake\Network\Response The response object. */ public function create(FilesystemInterface $cache, $path) { $stream = $cache->readStream($path); $contentType = $cache->getMimetype($path); $contentLength = (string) $cache->getSize($path); $response = new Response(); $response->type($contentType); $response->header('Content-Length', $contentLength); $response->body(function () use($stream) { rewind($stream); fpassthru($stream); fclose($stream); }); 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; } }
/** * test setting parameters in beforeDispatch method * * @return void */ public function testQueryStringAndCustomTime() { $folder = CACHE . 'views' . DS; $file = $folder . 'posts-home-coffee-life-sleep-sissies-coffee-life-sleep-sissies.html'; $content = '<!--cachetime:' . (time() + WEEK) . ';ext:html-->Foo bar'; file_put_contents($file, $content); Router::reload(); Router::connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']); Router::connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']); Router::connect('/:controller/:action/*'); $_GET = ['coffee' => 'life', 'sleep' => 'sissies']; $filter = new CacheFilter(); $request = new Request('posts/home/?coffee=life&sleep=sissies'); $response = new Response(); $event = new Event(__CLASS__, $this, compact('request', 'response')); $filter->beforeDispatch($event); $result = $response->body(); $expected = '<!--created:'; $this->assertTextStartsWith($expected, $result); $expected = '-->Foo bar'; $this->assertTextEndsWith($expected, $result); $result = $response->type(); $expected = 'text/html'; $this->assertEquals($expected, $result); $result = $response->header(); $this->assertNotEmpty($result['Expires']); // + 1 week unlink($file); }
public function testToPsrHeaders() { $cake = new CakeResponse(['status' => 403]); $cake->header(['X-testing' => ['one', 'two'], 'Location' => 'http://example.com/testing']); $result = ResponseTransformer::toPsr($cake); $expected = ['X-testing' => ['one', 'two'], 'Location' => ['http://example.com/testing'], 'Content-Type' => ['text/html']]; $this->assertSame($expected, $result->getHeaders()); }
/** * Asserts response headers * * @param string $header The header to check * @param string $content The content to check for. * @param string $message The failure message that will be appended to the generated message. * @return void */ public function assertHeader($header, $content, $message = '') { if (!$this->_response) { $this->fail('No response set, cannot assert headers. ' . $message); } $headers = $this->_response->header(); if (!isset($headers[$header])) { $this->fail("The '{$header}' header is not set. " . $message); } $this->assertEquals($headers[$header], $content, $message); }
/** * Sends an asset file to the client * * @param \Cake\Network\Request $request The request object to use. * @param \Cake\Network\Response $response The response object to use. * @param string $assetFile Path to the asset file in the file system * @param string $ext The extension of the file to determine its mime type * @return void */ protected function _deliverAsset(Request $request, Response $response, $assetFile, $ext) { $compressionEnabled = $response->compress(); if ($response->type($ext) === $ext) { $contentType = 'application/octet-stream'; $agent = $request->env('HTTP_USER_AGENT'); if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { $contentType = 'application/octetstream'; } $response->type($contentType); } if (!$compressionEnabled) { $response->header('Content-Length', filesize($assetFile)); } // $response->cache(filemtime($assetFile), $this->_cacheTime); $response->sendHeaders(); readfile($assetFile); if ($compressionEnabled) { ob_end_flush(); } }
/** * @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); //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); }
/** * Test CORS * * @dataProvider corsData * @param Request $request * @param string $origin * @param string|array $domains * @param string|array $methods * @param string|array $headers * @param string|bool $expectedOrigin * @param string|bool $expectedMethods * @param string|bool $expectedHeaders * @return void */ public function testCors($request, $origin, $domains, $methods, $headers, $expectedOrigin, $expectedMethods = false, $expectedHeaders = false) { $request->env('HTTP_ORIGIN', $origin); $response = new Response(); $result = $response->cors($request, $domains, $methods, $headers); $this->assertInstanceOf('Cake\\Network\\CorsBuilder', $result); $headers = $response->header(); if ($expectedOrigin) { $this->assertArrayHasKey('Access-Control-Allow-Origin', $headers); $this->assertEquals($expectedOrigin, $headers['Access-Control-Allow-Origin']); } if ($expectedMethods) { $this->assertArrayHasKey('Access-Control-Allow-Methods', $headers); $this->assertEquals($expectedMethods, $headers['Access-Control-Allow-Methods']); } if ($expectedHeaders) { $this->assertArrayHasKey('Access-Control-Allow-Headers', $headers); $this->assertEquals($expectedHeaders, $headers['Access-Control-Allow-Headers']); } unset($_SERVER['HTTP_ORIGIN']); }
/** * Tests the download method * * @return void */ public function testDownload() { $response = new Response(); $expected = ['Content-Disposition' => 'attachment; filename="myfile.mp3"']; $response->download('myfile.mp3'); $this->assertEquals($expected, $response->header()); }
/** * Sends an asset file to the client * * @param \Cake\Network\Request $request The request object to use. * @param \Cake\Network\Response $response The response object to use. * @param string $assetFile Path to the asset file in the file system * @param string $ext The extension of the file to determine its mime type * @return void */ protected function _deliverCacheFile(Request $request, Response $response, $file, $ext) { $compressionEnabled = $response->compress(); if ($response->type($ext) === $ext) { $contentType = 'application/octet-stream'; $agent = $request->env('HTTP_USER_AGENT'); if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent) || preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { $contentType = 'application/octetstream'; } $response->type($contentType); } if (!$compressionEnabled) { $response->header('Content-Length', filesize($file)); } $content = file_get_contents($file); $cacheInfo = $this->extractCacheInfo($content); $modifiedTime = filemtime($file); $cacheTime = $cacheInfo['time']; if (!$cacheTime) { $cacheTime = $this->_cacheTime; } $response->cache($modifiedTime, $cacheTime); $response->type($cacheInfo['ext']); if (Configure::read('debug') || $this->config('debug')) { if ($cacheInfo['ext'] === 'html') { $content = '<!--created:' . $modifiedTime . '-->' . $content; } } $response->body($content); }
/** * Convert a CakePHP response into a PSR7 one. * * @param \Cake\Network\Response $response The CakePHP response to convert * @return \Psr\Http\Message\ResponseInterface $response The equivalent PSR7 response. */ public static function toPsr(CakeResponse $response) { $status = $response->statusCode(); $headers = $response->header(); if (!isset($headers['Content-Type'])) { $headers = static::setContentType($headers, $response); } $cookies = $response->cookie(); if ($cookies && (session_status() === \PHP_SESSION_ACTIVE || PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg')) { $sessionCookie = session_get_cookie_params(); $sessionName = session_name(); $cookies[$sessionName] = ['name' => $sessionName, 'path' => $sessionCookie['path'], 'value' => session_id(), 'expire' => $sessionCookie['lifetime'], 'secure' => $sessionCookie['secure'], 'domain' => $sessionCookie['domain'], 'httpOnly' => $sessionCookie['httponly']]; } if ($cookies) { $headers['Set-Cookie'] = static::buildCookieHeader($cookies); } $stream = static::getStream($response); return new DiactorosResponse($stream, $status, $headers); }
/** * Tests setting of public/private Cache-Control directives * * @return void */ public function testSharable() { $response = $this->getMock('Cake\\Network\\Response', array('_sendHeader', '_sendContent')); $this->assertNull($response->sharable()); $response->sharable(true); $headers = $response->header(); $this->assertEquals('public', $headers['Cache-Control']); $response->expects($this->at(1))->method('_sendHeader')->with('Cache-Control', 'public'); $response->send(); $response = $this->getMock('Cake\\Network\\Response', array('_sendHeader', '_sendContent')); $response->sharable(false); $headers = $response->header(); $this->assertEquals('private', $headers['Cache-Control']); $response->expects($this->at(1))->method('_sendHeader')->with('Cache-Control', 'private'); $response->send(); $response = $this->getMock('Cake\\Network\\Response', array('_sendHeader', '_sendContent')); $response->sharable(true); $headers = $response->header(); $this->assertEquals('public', $headers['Cache-Control']); $response->sharable(false); $headers = $response->header(); $this->assertEquals('private', $headers['Cache-Control']); $response->expects($this->at(1))->method('_sendHeader')->with('Cache-Control', 'private'); $response->send(); $this->assertFalse($response->sharable()); $response->sharable(true); $this->assertTrue($response->sharable()); $response = new Response(); $response->sharable(true, 3600); $headers = $response->header(); $this->assertEquals('public, s-maxage=3600', $headers['Cache-Control']); $response = new Response(); $response->sharable(false, 3600); $headers = $response->header(); $this->assertEquals('private, max-age=3600', $headers['Cache-Control']); $response->send(); }
/** * Convert a CakePHP response into a PSR7 one. * * @param \Cake\Network\Response $response The CakePHP response to convert * @return \Psr\Http\Message\ResponseInterface $response The equivalent PSR7 response. */ public static function toPsr(CakeResponse $response) { $status = $response->statusCode(); $headers = $response->header(); if (!isset($headers['Content-Type'])) { $headers = static::setContentType($headers, $response); } $cookies = $response->cookie(); if ($cookies) { $headers['Set-Cookie'] = static::buildCookieHeader($cookies); } $stream = static::getStream($response); return new DiactorosResponse($stream, $status, $headers); }
/** * Extends response with X-headers containing rate limiting information. * * @param Cake\Network\Response $response Response instance * @return void */ protected function _setHeaders(Response $response) { if (!is_array($this->config('headers'))) { return; } $headers = $this->config('headers'); $response->header([$headers['limit'] => $this->config('limit'), $headers['remaining'] => $this->_getRemainingConnections(), $headers['reset'] => Cache::read($this->_getCacheExpirationKey(), static::$cacheConfig)]); }
/** * Helper for checking header values. * * @param \Cake\Network\Response $response The Response object. * @params string $header The header key to check */ protected function assertNoHeader(Response $response, $header) { $headers = $response->header(); $this->assertArrayNotHasKey($header, $headers, 'Header key was found.'); }
/** * 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(); }