PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/Cake/Network/CakeResponse.php

https://bitbucket.org/udeshika/fake_twitter
PHP | 695 lines | 418 code | 34 blank | 243 comment | 40 complexity | 86b2f6eef21fbfe7c3260fd036141496 MD5 | raw file
  1. <?php
  2. /**
  3. * CakeResponse
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://cakephp.org CakePHP(tm) Project
  15. * @package Cake.Network
  16. * @since CakePHP(tm) v 2.0
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. /**
  20. * CakeResponse is responsible for managing the response text, status and headers of a HTTP response.
  21. *
  22. * By default controllers will use this class to render their response. If you are going to use
  23. * a custom response class it should subclass this object in order to ensure compatibility.
  24. *
  25. * @package Cake.Network
  26. */
  27. class CakeResponse {
  28. /**
  29. * Holds HTTP response statuses
  30. *
  31. * @var array
  32. */
  33. protected $_statusCodes = array(
  34. 100 => 'Continue',
  35. 101 => 'Switching Protocols',
  36. 200 => 'OK',
  37. 201 => 'Created',
  38. 202 => 'Accepted',
  39. 203 => 'Non-Authoritative Information',
  40. 204 => 'No Content',
  41. 205 => 'Reset Content',
  42. 206 => 'Partial Content',
  43. 300 => 'Multiple Choices',
  44. 301 => 'Moved Permanently',
  45. 302 => 'Found',
  46. 303 => 'See Other',
  47. 304 => 'Not Modified',
  48. 305 => 'Use Proxy',
  49. 307 => 'Temporary Redirect',
  50. 400 => 'Bad Request',
  51. 401 => 'Unauthorized',
  52. 402 => 'Payment Required',
  53. 403 => 'Forbidden',
  54. 404 => 'Not Found',
  55. 405 => 'Method Not Allowed',
  56. 406 => 'Not Acceptable',
  57. 407 => 'Proxy Authentication Required',
  58. 408 => 'Request Time-out',
  59. 409 => 'Conflict',
  60. 410 => 'Gone',
  61. 411 => 'Length Required',
  62. 412 => 'Precondition Failed',
  63. 413 => 'Request Entity Too Large',
  64. 414 => 'Request-URI Too Large',
  65. 415 => 'Unsupported Media Type',
  66. 416 => 'Requested range not satisfiable',
  67. 417 => 'Expectation Failed',
  68. 500 => 'Internal Server Error',
  69. 501 => 'Not Implemented',
  70. 502 => 'Bad Gateway',
  71. 503 => 'Service Unavailable',
  72. 504 => 'Gateway Time-out'
  73. );
  74. /**
  75. * Holds known mime type mappings
  76. *
  77. * @var array
  78. */
  79. protected $_mimeTypes = array(
  80. 'ai' => 'application/postscript',
  81. 'bcpio' => 'application/x-bcpio',
  82. 'bin' => 'application/octet-stream',
  83. 'ccad' => 'application/clariscad',
  84. 'cdf' => 'application/x-netcdf',
  85. 'class' => 'application/octet-stream',
  86. 'cpio' => 'application/x-cpio',
  87. 'cpt' => 'application/mac-compactpro',
  88. 'csh' => 'application/x-csh',
  89. 'csv' => array('text/csv', 'application/vnd.ms-excel', 'text/plain'),
  90. 'dcr' => 'application/x-director',
  91. 'dir' => 'application/x-director',
  92. 'dms' => 'application/octet-stream',
  93. 'doc' => 'application/msword',
  94. 'drw' => 'application/drafting',
  95. 'dvi' => 'application/x-dvi',
  96. 'dwg' => 'application/acad',
  97. 'dxf' => 'application/dxf',
  98. 'dxr' => 'application/x-director',
  99. 'eot' => 'application/vnd.ms-fontobject',
  100. 'eps' => 'application/postscript',
  101. 'exe' => 'application/octet-stream',
  102. 'ez' => 'application/andrew-inset',
  103. 'flv' => 'video/x-flv',
  104. 'gtar' => 'application/x-gtar',
  105. 'gz' => 'application/x-gzip',
  106. 'bz2' => 'application/x-bzip',
  107. '7z' => 'application/x-7z-compressed',
  108. 'hdf' => 'application/x-hdf',
  109. 'hqx' => 'application/mac-binhex40',
  110. 'ico' => 'image/vnd.microsoft.icon',
  111. 'ips' => 'application/x-ipscript',
  112. 'ipx' => 'application/x-ipix',
  113. 'js' => 'text/javascript',
  114. 'latex' => 'application/x-latex',
  115. 'lha' => 'application/octet-stream',
  116. 'lsp' => 'application/x-lisp',
  117. 'lzh' => 'application/octet-stream',
  118. 'man' => 'application/x-troff-man',
  119. 'me' => 'application/x-troff-me',
  120. 'mif' => 'application/vnd.mif',
  121. 'ms' => 'application/x-troff-ms',
  122. 'nc' => 'application/x-netcdf',
  123. 'oda' => 'application/oda',
  124. 'otf' => 'font/otf',
  125. 'pdf' => 'application/pdf',
  126. 'pgn' => 'application/x-chess-pgn',
  127. 'pot' => 'application/mspowerpoint',
  128. 'pps' => 'application/mspowerpoint',
  129. 'ppt' => 'application/mspowerpoint',
  130. 'ppz' => 'application/mspowerpoint',
  131. 'pre' => 'application/x-freelance',
  132. 'prt' => 'application/pro_eng',
  133. 'ps' => 'application/postscript',
  134. 'roff' => 'application/x-troff',
  135. 'scm' => 'application/x-lotusscreencam',
  136. 'set' => 'application/set',
  137. 'sh' => 'application/x-sh',
  138. 'shar' => 'application/x-shar',
  139. 'sit' => 'application/x-stuffit',
  140. 'skd' => 'application/x-koan',
  141. 'skm' => 'application/x-koan',
  142. 'skp' => 'application/x-koan',
  143. 'skt' => 'application/x-koan',
  144. 'smi' => 'application/smil',
  145. 'smil' => 'application/smil',
  146. 'sol' => 'application/solids',
  147. 'spl' => 'application/x-futuresplash',
  148. 'src' => 'application/x-wais-source',
  149. 'step' => 'application/STEP',
  150. 'stl' => 'application/SLA',
  151. 'stp' => 'application/STEP',
  152. 'sv4cpio' => 'application/x-sv4cpio',
  153. 'sv4crc' => 'application/x-sv4crc',
  154. 'svg' => 'image/svg+xml',
  155. 'svgz' => 'image/svg+xml',
  156. 'swf' => 'application/x-shockwave-flash',
  157. 't' => 'application/x-troff',
  158. 'tar' => 'application/x-tar',
  159. 'tcl' => 'application/x-tcl',
  160. 'tex' => 'application/x-tex',
  161. 'texi' => 'application/x-texinfo',
  162. 'texinfo' => 'application/x-texinfo',
  163. 'tr' => 'application/x-troff',
  164. 'tsp' => 'application/dsptype',
  165. 'ttf' => 'font/ttf',
  166. 'unv' => 'application/i-deas',
  167. 'ustar' => 'application/x-ustar',
  168. 'vcd' => 'application/x-cdlink',
  169. 'vda' => 'application/vda',
  170. 'xlc' => 'application/vnd.ms-excel',
  171. 'xll' => 'application/vnd.ms-excel',
  172. 'xlm' => 'application/vnd.ms-excel',
  173. 'xls' => 'application/vnd.ms-excel',
  174. 'xlw' => 'application/vnd.ms-excel',
  175. 'zip' => 'application/zip',
  176. 'aif' => 'audio/x-aiff',
  177. 'aifc' => 'audio/x-aiff',
  178. 'aiff' => 'audio/x-aiff',
  179. 'au' => 'audio/basic',
  180. 'kar' => 'audio/midi',
  181. 'mid' => 'audio/midi',
  182. 'midi' => 'audio/midi',
  183. 'mp2' => 'audio/mpeg',
  184. 'mp3' => 'audio/mpeg',
  185. 'mpga' => 'audio/mpeg',
  186. 'ogg' => 'audio/ogg',
  187. 'ra' => 'audio/x-realaudio',
  188. 'ram' => 'audio/x-pn-realaudio',
  189. 'rm' => 'audio/x-pn-realaudio',
  190. 'rpm' => 'audio/x-pn-realaudio-plugin',
  191. 'snd' => 'audio/basic',
  192. 'tsi' => 'audio/TSP-audio',
  193. 'wav' => 'audio/x-wav',
  194. 'asc' => 'text/plain',
  195. 'c' => 'text/plain',
  196. 'cc' => 'text/plain',
  197. 'css' => 'text/css',
  198. 'etx' => 'text/x-setext',
  199. 'f' => 'text/plain',
  200. 'f90' => 'text/plain',
  201. 'h' => 'text/plain',
  202. 'hh' => 'text/plain',
  203. 'html' => array('text/html', '*/*'),
  204. 'htm' => array('text/html', '*/*'),
  205. 'm' => 'text/plain',
  206. 'rtf' => 'text/rtf',
  207. 'rtx' => 'text/richtext',
  208. 'sgm' => 'text/sgml',
  209. 'sgml' => 'text/sgml',
  210. 'tsv' => 'text/tab-separated-values',
  211. 'tpl' => 'text/template',
  212. 'txt' => 'text/plain',
  213. 'text' => 'text/plain',
  214. 'xml' => array('application/xml', 'text/xml'),
  215. 'avi' => 'video/x-msvideo',
  216. 'fli' => 'video/x-fli',
  217. 'mov' => 'video/quicktime',
  218. 'movie' => 'video/x-sgi-movie',
  219. 'mpe' => 'video/mpeg',
  220. 'mpeg' => 'video/mpeg',
  221. 'mpg' => 'video/mpeg',
  222. 'qt' => 'video/quicktime',
  223. 'viv' => 'video/vnd.vivo',
  224. 'vivo' => 'video/vnd.vivo',
  225. 'gif' => 'image/gif',
  226. 'ief' => 'image/ief',
  227. 'jpe' => 'image/jpeg',
  228. 'jpeg' => 'image/jpeg',
  229. 'jpg' => 'image/jpeg',
  230. 'pbm' => 'image/x-portable-bitmap',
  231. 'pgm' => 'image/x-portable-graymap',
  232. 'png' => 'image/png',
  233. 'pnm' => 'image/x-portable-anymap',
  234. 'ppm' => 'image/x-portable-pixmap',
  235. 'ras' => 'image/cmu-raster',
  236. 'rgb' => 'image/x-rgb',
  237. 'tif' => 'image/tiff',
  238. 'tiff' => 'image/tiff',
  239. 'xbm' => 'image/x-xbitmap',
  240. 'xpm' => 'image/x-xpixmap',
  241. 'xwd' => 'image/x-xwindowdump',
  242. 'ice' => 'x-conference/x-cooltalk',
  243. 'iges' => 'model/iges',
  244. 'igs' => 'model/iges',
  245. 'mesh' => 'model/mesh',
  246. 'msh' => 'model/mesh',
  247. 'silo' => 'model/mesh',
  248. 'vrml' => 'model/vrml',
  249. 'wrl' => 'model/vrml',
  250. 'mime' => 'www/mime',
  251. 'pdb' => 'chemical/x-pdb',
  252. 'xyz' => 'chemical/x-pdb',
  253. 'javascript' => 'text/javascript',
  254. 'json' => 'application/json',
  255. 'form' => 'application/x-www-form-urlencoded',
  256. 'file' => 'multipart/form-data',
  257. 'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
  258. 'xhtml-mobile' => 'application/vnd.wap.xhtml+xml',
  259. 'rss' => 'application/rss+xml',
  260. 'atom' => 'application/atom+xml',
  261. 'amf' => 'application/x-amf',
  262. 'wap' => array('text/vnd.wap.wml', 'text/vnd.wap.wmlscript', 'image/vnd.wap.wbmp'),
  263. 'wml' => 'text/vnd.wap.wml',
  264. 'wmlscript' => 'text/vnd.wap.wmlscript',
  265. 'wbmp' => 'image/vnd.wap.wbmp',
  266. );
  267. /**
  268. * Protocol header to send to the client
  269. *
  270. * @var string
  271. */
  272. protected $_protocol = 'HTTP/1.1';
  273. /**
  274. * Status code to send to the client
  275. *
  276. * @var integer
  277. */
  278. protected $_status = 200;
  279. /**
  280. * Content type to send. This can be an 'extension' that will be transformed using the $_mimetypes array
  281. * or a complete mime-type
  282. *
  283. * @var integer
  284. */
  285. protected $_contentType = 'text/html';
  286. /**
  287. * Buffer list of headers
  288. *
  289. * @var array
  290. */
  291. protected $_headers = array();
  292. /**
  293. * Buffer string for response message
  294. *
  295. * @var string
  296. */
  297. protected $_body = null;
  298. /**
  299. * The charset the response body is encoded with
  300. *
  301. * @var string
  302. */
  303. protected $_charset = 'UTF-8';
  304. /**
  305. * Class constructor
  306. *
  307. * @param array $options list of parameters to setup the response. Possible values are:
  308. * - body: the response text that should be sent to the client
  309. * - status: the HTTP status code to respond with
  310. * - type: a complete mime-type string or an extension mapped in this class
  311. * - charset: the charset for the response body
  312. */
  313. public function __construct(array $options = array()) {
  314. if (isset($options['body'])) {
  315. $this->body($options['body']);
  316. }
  317. if (isset($options['status'])) {
  318. $this->statusCode($options['status']);
  319. }
  320. if (isset($options['type'])) {
  321. $this->type($options['type']);
  322. }
  323. if (isset($options['charset'])) {
  324. $this->charset($options['charset']);
  325. }
  326. }
  327. /**
  328. * Sends the complete response to the client including headers and message body.
  329. * Will echo out the content in the response body.
  330. *
  331. * @return void
  332. */
  333. public function send() {
  334. if (isset($this->_headers['Location']) && $this->_status === 200) {
  335. $this->statusCode(302);
  336. }
  337. $codeMessage = $this->_statusCodes[$this->_status];
  338. $this->_sendHeader("{$this->_protocol} {$this->_status} {$codeMessage}");
  339. $this->_sendHeader('Content-Type', "{$this->_contentType}; charset={$this->_charset}");
  340. $this->_setContentLength();
  341. foreach ($this->_headers as $header => $value) {
  342. $this->_sendHeader($header, $value);
  343. }
  344. $this->_sendContent($this->_body);
  345. }
  346. /**
  347. * Calculates the correct Content-Length and sets it as a header in the response
  348. * Will not set the value if already set or if the output is compressed.
  349. *
  350. * @return void
  351. */
  352. protected function _setContentLength() {
  353. $shouldSetLength = empty($this->_headers['Content-Length']) && !in_array($this->_status, range(301, 307));
  354. if ($shouldSetLength && !$this->outputCompressed()) {
  355. $offset = ob_get_level() ? ob_get_length() : 0;
  356. if (ini_get('mbstring.func_overload') & 2 && function_exists('mb_strlen')) {
  357. $this->_headers['Content-Length'] = $offset + mb_strlen($this->_body, '8bit');
  358. } else {
  359. $this->_headers['Content-Length'] = $offset + strlen($this->_body);
  360. }
  361. }
  362. }
  363. /**
  364. * Sends a header to the client.
  365. *
  366. * @param string $name the header name
  367. * @param string $value the header value
  368. * @return void
  369. */
  370. protected function _sendHeader($name, $value = null) {
  371. if (!headers_sent()) {
  372. if (is_null($value)) {
  373. header($name);
  374. } else {
  375. header("{$name}: {$value}");
  376. }
  377. }
  378. }
  379. /**
  380. * Sends a content string to the client.
  381. *
  382. * @param string $content string to send as response body
  383. * @return void
  384. */
  385. protected function _sendContent($content) {
  386. echo $content;
  387. }
  388. /**
  389. * Buffers a header string to be sent
  390. * Returns the complete list of buffered headers
  391. *
  392. * ### Single header
  393. * e.g `header('Location', 'http://example.com');`
  394. *
  395. * ### Multiple headers
  396. * e.g `header(array('Location' => 'http://example.com', 'X-Extra' => 'My header'));`
  397. *
  398. * ### String header
  399. * e.g `header('WWW-Authenticate: Negotiate');`
  400. *
  401. * ### Array of string headers
  402. * e.g `header(array('WWW-Authenticate: Negotiate', 'Content-type: application/pdf'));`
  403. *
  404. * Multiple calls for setting the same header name will have the same effect as setting the header once
  405. * with the last value sent for it
  406. * e.g `header('WWW-Authenticate: Negotiate'); header('WWW-Authenticate: Not-Negotiate');`
  407. * will have the same effect as only doing `header('WWW-Authenticate: Not-Negotiate');`
  408. *
  409. * @param mixed $header. An array of header strings or a single header string
  410. * - an associative array of "header name" => "header value" is also accepted
  411. * - an array of string headers is also accepted
  412. * @param mixed $value. The header value.
  413. * @return array list of headers to be sent
  414. */
  415. public function header($header = null, $value = null) {
  416. if (is_null($header)) {
  417. return $this->_headers;
  418. }
  419. if (is_array($header)) {
  420. foreach ($header as $h => $v) {
  421. if (is_numeric($h)) {
  422. $this->header($v);
  423. continue;
  424. }
  425. $this->_headers[$h] = trim($v);
  426. }
  427. return $this->_headers;
  428. }
  429. if (!is_null($value)) {
  430. $this->_headers[$header] = $value;
  431. return $this->_headers;
  432. }
  433. list($header, $value) = explode(':', $header, 2);
  434. $this->_headers[$header] = trim($value);
  435. return $this->_headers;
  436. }
  437. /**
  438. * Buffers the response message to be sent
  439. * if $content is null the current buffer is returned
  440. *
  441. * @param string $content the string message to be sent
  442. * @return string current message buffer if $content param is passed as null
  443. */
  444. public function body($content = null) {
  445. if (is_null($content)) {
  446. return $this->_body;
  447. }
  448. return $this->_body = $content;
  449. }
  450. /**
  451. * Sets the HTTP status code to be sent
  452. * if $code is null the current code is returned
  453. *
  454. * @param integer $code
  455. * @return integer current status code
  456. * @throws CakeException When an unknown status code is reached.
  457. */
  458. public function statusCode($code = null) {
  459. if (is_null($code)) {
  460. return $this->_status;
  461. }
  462. if (!isset($this->_statusCodes[$code])) {
  463. throw new CakeException(__d('cake_dev', 'Unknown status code'));
  464. }
  465. return $this->_status = $code;
  466. }
  467. /**
  468. * Queries & sets valid HTTP response codes & messages.
  469. *
  470. * @param mixed $code If $code is an integer, then the corresponding code/message is
  471. * returned if it exists, null if it does not exist. If $code is an array,
  472. * then the 'code' and 'message' keys of each nested array are added to the default
  473. * HTTP codes. Example:
  474. *
  475. * httpCodes(404); // returns array(404 => 'Not Found')
  476. *
  477. * httpCodes(array(
  478. * 701 => 'Unicorn Moved',
  479. * 800 => 'Unexpected Minotaur'
  480. * )); // sets these new values, and returns true
  481. *
  482. * @return mixed associative array of the HTTP codes as keys, and the message
  483. * strings as values, or null of the given $code does not exist.
  484. */
  485. public function httpCodes($code = null) {
  486. if (empty($code)) {
  487. return $this->_statusCodes;
  488. }
  489. if (is_array($code)) {
  490. $this->_statusCodes = $code + $this->_statusCodes;
  491. return true;
  492. }
  493. if (!isset($this->_statusCodes[$code])) {
  494. return null;
  495. }
  496. return array($code => $this->_statusCodes[$code]);
  497. }
  498. /**
  499. * Sets the response content type. It can be either a file extension
  500. * which will be mapped internally to a mime-type or a string representing a mime-type
  501. * if $contentType is null the current content type is returned
  502. * if $contentType is an associative array, it will be stored as a content type definition
  503. *
  504. * ### Setting the content type
  505. *
  506. * e.g `type('jpg');`
  507. *
  508. * ### Returning the current content type
  509. *
  510. * e.g `type();`
  511. *
  512. * ### Storing a content type definition
  513. *
  514. * e.g `type(array('keynote' => 'application/keynote'));`
  515. *
  516. * ### Replacing a content type definition
  517. *
  518. * e.g `type(array('jpg' => 'text/plain'));`
  519. *
  520. * @param string $contentType
  521. * @return mixed current content type or false if supplied an invalid content type
  522. */
  523. public function type($contentType = null) {
  524. if (is_null($contentType)) {
  525. return $this->_contentType;
  526. }
  527. if (is_array($contentType)) {
  528. $type = key($contentType);
  529. $defitition = current($contentType);
  530. $this->_mimeTypes[$type] = $defitition;
  531. return $this->_contentType;
  532. }
  533. if (isset($this->_mimeTypes[$contentType])) {
  534. $contentType = $this->_mimeTypes[$contentType];
  535. $contentType = is_array($contentType) ? current($contentType) : $contentType;
  536. }
  537. if (strpos($contentType, '/') === false) {
  538. return false;
  539. }
  540. return $this->_contentType = $contentType;
  541. }
  542. /**
  543. * Returns the mime type definition for an alias
  544. *
  545. * e.g `getMimeType('pdf'); // returns 'application/pdf'`
  546. *
  547. * @param string $alias the content type alias to map
  548. * @return mixed string mapped mime type or false if $alias is not mapped
  549. */
  550. public function getMimeType($alias) {
  551. if (isset($this->_mimeTypes[$alias])) {
  552. return $this->_mimeTypes[$alias];
  553. }
  554. return false;
  555. }
  556. /**
  557. * Maps a content-type back to an alias
  558. *
  559. * e.g `mapType('application/pdf'); // returns 'pdf'`
  560. *
  561. * @param mixed $ctype Either a string content type to map, or an array of types.
  562. * @return mixed Aliases for the types provided.
  563. */
  564. public function mapType($ctype) {
  565. if (is_array($ctype)) {
  566. return array_map(array($this, 'mapType'), $ctype);
  567. }
  568. foreach ($this->_mimeTypes as $alias => $types) {
  569. if (is_array($types) && in_array($ctype, $types)) {
  570. return $alias;
  571. } elseif (is_string($types) && $types == $ctype) {
  572. return $alias;
  573. }
  574. }
  575. return null;
  576. }
  577. /**
  578. * Sets the response charset
  579. * if $charset is null the current charset is returned
  580. *
  581. * @param string $charset
  582. * @return string current charset
  583. */
  584. public function charset($charset = null) {
  585. if (is_null($charset)) {
  586. return $this->_charset;
  587. }
  588. return $this->_charset = $charset;
  589. }
  590. /**
  591. * Sets the correct headers to instruct the client to not cache the response
  592. *
  593. * @return void
  594. */
  595. public function disableCache() {
  596. $this->header(array(
  597. 'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
  598. 'Last-Modified' => gmdate("D, d M Y H:i:s") . " GMT",
  599. 'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
  600. 'Pragma' => 'no-cache'
  601. ));
  602. }
  603. /**
  604. * Sets the correct headers to instruct the client to cache the response.
  605. *
  606. * @param string $since a valid time since the response text has not been modified
  607. * @param string $time a valid time for cache expiry
  608. * @return void
  609. */
  610. public function cache($since, $time = '+1 day') {
  611. if (!is_integer($time)) {
  612. $time = strtotime($time);
  613. }
  614. $this->header(array(
  615. 'Date' => gmdate("D, j M Y G:i:s ", time()) . 'GMT',
  616. 'Last-Modified' => gmdate("D, j M Y G:i:s ", $since) . 'GMT',
  617. 'Expires' => gmdate("D, j M Y H:i:s", $time) . " GMT",
  618. 'Cache-Control' => 'public, max-age=' . ($time - time()),
  619. 'Pragma' => 'cache'
  620. ));
  621. }
  622. /**
  623. * Sets the correct output buffering handler to send a compressed response. Responses will
  624. * be compressed with zlib, if the extension is available.
  625. *
  626. * @return boolean false if client does not accept compressed responses or no handler is available, true otherwise
  627. */
  628. public function compress() {
  629. $compressionEnabled = ini_get("zlib.output_compression") !== '1' &&
  630. extension_loaded("zlib") &&
  631. (strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false);
  632. return $compressionEnabled && ob_start('ob_gzhandler');
  633. }
  634. /**
  635. * Returns whether the resulting output will be compressed by PHP
  636. *
  637. * @return boolean
  638. */
  639. public function outputCompressed() {
  640. return strpos(env('HTTP_ACCEPT_ENCODING'), 'gzip') !== false
  641. && (ini_get("zlib.output_compression") === '1' || in_array('ob_gzhandler', ob_list_handlers()));
  642. }
  643. /**
  644. * Sets the correct headers to instruct the browser to download the response as a file.
  645. *
  646. * @param string $filename the name of the file as the browser will download the response
  647. * @return void
  648. */
  649. public function download($filename) {
  650. $this->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
  651. }
  652. /**
  653. * String conversion. Fetches the response body as a string.
  654. * Does *not* send headers.
  655. *
  656. * @return string
  657. */
  658. public function __toString() {
  659. return (string)$this->_body;
  660. }
  661. }