diff options
Diffstat (limited to 'api/Slim/Http/Response.php')
-rwxr-xr-x | api/Slim/Http/Response.php | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/api/Slim/Http/Response.php b/api/Slim/Http/Response.php new file mode 100755 index 0000000..5414edb --- /dev/null +++ b/api/Slim/Http/Response.php @@ -0,0 +1,321 @@ +<?php +/** + * Slim - a micro PHP 5 framework + * + * @author Josh Lockhart <info@joshlockhart.com> + * @copyright 2011 Josh Lockhart + * @link http://www.slimframework.com + * @license http://www.slimframework.com/license + * @version 1.5.0 + * + * MIT LICENSE + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * Response + * + * Object-oriented representation of an HTTP response that is + * returned to the client. This class is responsible for: + * + * - HTTP response status + * - HTTP response body + * - HTTP response headers + * - HTTP response cookies + * + * @package Slim + * @author Josh Lockhart <info@joshlockhart.com> + * @author Kris Jordan <http://github.com/KrisJordan> + * @since Version 1.0 + */ +class Slim_Http_Response { + + /** + * @var Slim_Http_Request + */ + protected $request; + + /** + * @var string + */ + protected $httpVersion = '1.1'; + + /** + * @var int HTTP status code + */ + protected $status = 200; + + /** + * @var array Key-value array of HTTP response headers + */ + protected $headers = array(); + + /** + * @var string HTTP response body + */ + protected $body = ''; + + /** + * @var int Length of HTTP response body + */ + protected $length = 0; + + /** + * @var array HTTP response codes and messages + */ + protected static $messages = array( + //Informational 1xx + 100 => '100 Continue', + 101 => '101 Switching Protocols', + //Successful 2xx + 200 => '200 OK', + 201 => '201 Created', + 202 => '202 Accepted', + 203 => '203 Non-Authoritative Information', + 204 => '204 No Content', + 205 => '205 Reset Content', + 206 => '206 Partial Content', + //Redirection 3xx + 300 => '300 Multiple Choices', + 301 => '301 Moved Permanently', + 302 => '302 Found', + 303 => '303 See Other', + 304 => '304 Not Modified', + 305 => '305 Use Proxy', + 306 => '306 (Unused)', + 307 => '307 Temporary Redirect', + //Client Error 4xx + 400 => '400 Bad Request', + 401 => '401 Unauthorized', + 402 => '402 Payment Required', + 403 => '403 Forbidden', + 404 => '404 Not Found', + 405 => '405 Method Not Allowed', + 406 => '406 Not Acceptable', + 407 => '407 Proxy Authentication Required', + 408 => '408 Request Timeout', + 409 => '409 Conflict', + 410 => '410 Gone', + 411 => '411 Length Required', + 412 => '412 Precondition Failed', + 413 => '413 Request Entity Too Large', + 414 => '414 Request-URI Too Long', + 415 => '415 Unsupported Media Type', + 416 => '416 Requested Range Not Satisfiable', + 417 => '417 Expectation Failed', + 422 => '422 Unprocessable Entity', + 423 => '423 Locked', + //Server Error 5xx + 500 => '500 Internal Server Error', + 501 => '501 Not Implemented', + 502 => '502 Bad Gateway', + 503 => '503 Service Unavailable', + 504 => '504 Gateway Timeout', + 505 => '505 HTTP Version Not Supported' + ); + + /** + * @var CookieJar Manages Cookies to be sent with this Response + */ + protected $cookieJar; + + /** + * Constructor + */ + public function __construct( Slim_Http_Request $req ) { + $this->request = $req; + $this->header('Content-Type', 'text/html'); + } + + /** + * Set and/or get the HTTP response version + * @param string $version + * @return void + * @throws InvalidArgumentException If argument is not a valid HTTP version + */ + public function httpVersion( $version = null ) { + if ( $version ) { + $version = (string)$version; + if ( $version === '1.0' || $version === '1.1' ) { + $this->httpVersion = $version; + } else { + throw new InvalidArgumentException('Invalid HTTP version in Response object'); + } + } + return $this->httpVersion; + } + + /** + * Set and/or get the HTTP response status code + * @param int $status + * @return int + * @throws InvalidArgumentException If argument is not a valid HTTP status code + */ + public function status( $status = null ) { + if ( !is_null($status) ) { + if ( !in_array(intval($status), array_keys(self::$messages)) ) { + throw new InvalidArgumentException('Cannot set Response status. Provided status code "' . $status . '" is not a valid HTTP response code.'); + } + $this->status = intval($status); + } + return $this->status; + } + + /** + * Get HTTP response headers + * @return array + */ + public function headers() { + return $this->headers; + } + + /** + * Get and/or set an HTTP response header + * @param string $key The header name + * @param string $value The header value + * @return string|null The header value, or NULL if header not set + */ + public function header( $key, $value = null ) { + if ( !is_null($value) ) { + $this->headers[$key] = $value; + } + return isset($this->headers[$key]) ? $this->headers[$key] : null; + } + + /** + * Set the HTTP response body + * @param string $body The new HTTP response body + * @return string The new HTTP response body + */ + public function body( $body = null ) { + if ( !is_null($body) ) { + $this->body = ''; + $this->length = 0; + $this->write($body); + } + return $this->body; + } + + /** + * Append the HTTP response body + * @param string $body Content to append to the current HTTP response body + * @return string The updated HTTP response body + */ + public function write( $body ) { + $body = (string)$body; + $this->length += strlen($body); + $this->body .= $body; + $this->header('Content-Length', $this->length); + return $body; + } + + /** + * Set cookie jar + * @param Slim_Http_CookieJar $cookieJar + * @return void + */ + public function setCookieJar( Slim_Http_CookieJar $cookieJar ) { + $this->cookieJar = $cookieJar; + } + + /** + * Get cookie jar + * @return Slim_Http_CookieJar + */ + public function getCookieJar() { + return $this->cookieJar; + } + + /** + * Finalize response headers before response is sent + * @return void + */ + public function finalize() { + if ( in_array($this->status, array(204, 304)) ) { + $this->body(''); + unset($this->headers['Content-Type']); + } + } + + /** + * Get message for HTTP status code + * @return string|null + */ + public static function getMessageForCode( $status ) { + return isset(self::$messages[$status]) ? self::$messages[$status] : null; + } + + /** + * Can this HTTP response have a body? + * @return bool + */ + public function canHaveBody() { + return ( $this->status < 100 || $this->status >= 200 ) && $this->status != 204 && $this->status != 304; + } + + /** + * Send headers for HTTP response + * @return void + */ + protected function sendHeaders() { + //Finalize response + $this->finalize(); + + if ( substr(PHP_SAPI, 0, 3) === 'cgi') { + //Send Status header if running with fastcgi + header('Status: ' . self::getMessageForCode($this->status())); + } else { + //Else send HTTP message + header(sprintf('HTTP/%s %s', $this->httpVersion, self::getMessageForCode($this->status()))); + } + + //Send headers + foreach ( $this->headers() as $name => $value ) { + header("$name: $value"); + } + + //Send cookies + foreach ( $this->getCookieJar()->getResponseCookies() as $name => $cookie ) { + setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpires(), $cookie->getPath(), $cookie->getDomain(), $cookie->getSecure(), $cookie->getHttpOnly()); + } + + //Flush all output to client + flush(); + } + + /** + * Send HTTP response + * + * This method will set Response headers, set Response cookies, + * and `echo` the Response body to the current output buffer. + * + * @return void + */ + public function send() { + if ( !headers_sent() ) { + $this->sendHeaders(); + } + if ( $this->canHaveBody() && $this->request->isHead() === false ) { + echo $this->body; + } + } + +}
\ No newline at end of file |