From ba0da059da109c26a8ef7ca965ac2a7b9db13af1 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 7 Jun 2013 08:00:47 -0400 Subject: [PATCH] response WIP --- framework/yii/base/HttpException.php | 65 +---------- framework/yii/web/Response.php | 216 ++++++++++++++++++++++++++++++++--- 2 files changed, 207 insertions(+), 74 deletions(-) diff --git a/framework/yii/base/HttpException.php b/framework/yii/base/HttpException.php index 4d63764..b1478b0 100644 --- a/framework/yii/base/HttpException.php +++ b/framework/yii/base/HttpException.php @@ -7,6 +7,9 @@ namespace yii\base; +use yii\web\Response; + + /** * HttpException represents an exception caused by an improper request of the end-user. * @@ -42,66 +45,8 @@ class HttpException extends UserException */ public function getName() { - static $httpCodes = array( - 100 => 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - 118 => 'Connection timed out', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 207 => 'Multi-Status', - 210 => 'Content Different', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 307 => 'Temporary Redirect', - 310 => 'Too many Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Time-out', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested range unsatisfiable', - 417 => 'Expectation failed', - 418 => 'I’m a teapot', - 422 => 'Unprocessable entity', - 423 => 'Locked', - 424 => 'Method failure', - 425 => 'Unordered Collection', - 426 => 'Upgrade Required', - 449 => 'Retry With', - 450 => 'Blocked by Windows Parental Controls', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway ou Proxy Error', - 503 => 'Service Unavailable', - 504 => 'Gateway Time-out', - 505 => 'HTTP Version not supported', - 507 => 'Insufficient storage', - 509 => 'Bandwidth Limit Exceeded', - ); - - if (isset($httpCodes[$this->statusCode])) { - return $httpCodes[$this->statusCode]; + if (isset(Response::$statusTexts[$this->statusCode])) { + return Response::$statusTexts[$this->statusCode]; } else { return 'Error'; } diff --git a/framework/yii/web/Response.php b/framework/yii/web/Response.php index ea1d57e..93c031e 100644 --- a/framework/yii/web/Response.php +++ b/framework/yii/web/Response.php @@ -8,8 +8,8 @@ namespace yii\web; use Yii; -use XMLWriter; use yii\base\HttpException; +use yii\base\InvalidParamException; use yii\helpers\FileHelper; use yii\helpers\Html; use yii\helpers\Json; @@ -34,10 +34,117 @@ class Response extends \yii\base\Response */ public $content; /** + * @var string + */ + public $statusText; + /** + * @var string the charset to use. If not set, [[\yii\base\Application::charset]] will be used. + */ + public $charset; + /** + * @var string the version of the HTTP protocol to use + */ + public $version = '1.0'; + + /** + * @var array list of HTTP status codes and the corresponding texts + */ + public static $statusTexts = array( + 100 => 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + 118 => 'Connection timed out', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 208 => 'Already Reported', + 210 => 'Content Different', + 226 => 'IM Used', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 306 => 'Reserved', + 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', + 310 => 'Too many Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Time-out', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested range unsatisfiable', + 417 => 'Expectation failed', + 418 => 'I’m a teapot', + 422 => 'Unprocessable entity', + 423 => 'Locked', + 424 => 'Method failure', + 425 => 'Unordered Collection', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 449 => 'Retry With', + 450 => 'Blocked by Windows Parental Controls', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway ou Proxy Error', + 503 => 'Service Unavailable', + 504 => 'Gateway Time-out', + 505 => 'HTTP Version not supported', + 507 => 'Insufficient storage', + 508 => 'Loop Detected', + 509 => 'Bandwidth Limit Exceeded', + 510 => 'Not Extended', + 511 => 'Network Authentication Required', + ); + + private $_statusCode = 200; + /** * @var HeaderCollection */ private $_headers; + + public function init() + { + if ($this->charset === null) { + $this->charset = Yii::$app->charset; + } + } + + public function getStatusCode() + { + return $this->_statusCode; + } + + public function setStatusCode($value) + { + $this->_statusCode = (int)$value; + if ($this->isInvalid()) { + throw new InvalidParamException("The HTTP status code is invalid: $value"); + } + $this->statusText = isset(self::$statusTexts[$this->_statusCode]) ? self::$statusTexts[$this->_statusCode] : 'Error'; + } + /** * Returns the header collection. * The header collection contains the currently registered HTTP headers. @@ -75,7 +182,7 @@ class Response extends \yii\base\Response */ public function getEtag() { - return $this->getHeaders()->get("ETag"); + return $this->getHeaders()->get('ETag'); } /** @@ -84,7 +191,7 @@ class Response extends \yii\base\Response */ public function setEtag($value) { - $this->getHeaders()->set("ETag", $value); + $this->getHeaders()->set('ETag', $value); } /** @@ -93,7 +200,7 @@ class Response extends \yii\base\Response */ public function getLastModified() { - return $this->getHeaders()->get("Last-Modified"); + return $this->getHeaders()->get('Last-Modified'); } /** @@ -102,7 +209,7 @@ class Response extends \yii\base\Response */ public function setLastModified($value) { - $this->getHeaders()->set("Last-Modified", $value); + $this->getHeaders()->set('Last-Modified', $value); } /** @@ -111,7 +218,7 @@ class Response extends \yii\base\Response */ public function getContentType() { - return $this->getHeaders()->get("Content-type"); + return $this->getHeaders()->get('Content-type'); } /** @@ -120,7 +227,7 @@ class Response extends \yii\base\Response */ public function setContentType($value) { - $this->getHeaders()->set("Content-type", $value); + $this->getHeaders()->set('Content-type', $value); } /** @@ -129,29 +236,29 @@ class Response extends \yii\base\Response */ public function getContentDisposition() { - return $this->getHeaders()->get("Content-Disposition"); + return $this->getHeaders()->get('Content-Disposition'); } /** * Sets the content disposition header to send - * @param string $contentDisposition the content disposition header + * @param string $value the content disposition header */ - public function setContentDisposition($contentDisposition) + public function setContentDisposition($value) { - $this->getHeaders()->set("Content-Disposition", $contentDisposition); + $this->getHeaders()->set('Content-Disposition', $value); } public function renderJson($data) { - $this->setContentType("application/json"); + $this->setContentType('application/json'); $this->content = Json::encode($data); } public function renderJsonp($callbackName, $data) { - $this->setContentType("application/json"); + $this->setContentType('text/javascript'); $data = Json::encode($data); - $this->content = "$callbackName($data)"; + $this->content = "$callbackName($data);"; } /** @@ -169,6 +276,7 @@ class Response extends \yii\base\Response */ protected function sendHeaders() { + header("HTTP/{$this->version} " . $this->getStatusCode() . " {$this->statusText}"); foreach ($this->_headers as $name => $values) { foreach ($values as $value) { header("$name: $value"); @@ -446,4 +554,84 @@ class Response extends \yii\base\Response { return Yii::$app->getRequest()->getCookies(); } + + /** + * @return boolean whether this response has a valid [[statusCode]]. + */ + public function isInvalid() + { + return $this->getStatusCode() < 100 || $this->getStatusCode() >= 600; + } + + /** + * @return boolean whether this response is informational + */ + public function isInformational() + { + return $this->getStatusCode() >= 100 && $this->getStatusCode() < 200; + } + + /** + * @return boolean whether this response is successfully + */ + public function isSuccessful() + { + return $this->getStatusCode() >= 200 && $this->getStatusCode() < 300; + } + + /** + * @return boolean whether this response is a redirection + */ + public function isRedirection() + { + return $this->getStatusCode() >= 300 && $this->getStatusCode() < 400; + } + + /** + * @return boolean whether this response indicates a client error + */ + public function isClientError() + { + return $this->getStatusCode() >= 400 && $this->getStatusCode() < 500; + } + + /** + * @return boolean whether this response indicates a server error + */ + public function isServerError() + { + return $this->getStatusCode() >= 500 && $this->getStatusCode() < 600; + } + + /** + * @return boolean whether this response is OK + */ + public function isOk() + { + return 200 === $this->getStatusCode(); + } + + /** + * @return boolean whether this response indicates the current request is forbidden + */ + public function isForbidden() + { + return 403 === $this->getStatusCode(); + } + + /** + * @return boolean whether this response indicates the currently requested resource is not found + */ + public function isNotFound() + { + return 404 === $this->getStatusCode(); + } + + /** + * @return boolean whether this response is empty + */ + public function isEmpty() + { + return in_array($this->getStatusCode(), array(201, 204, 304)); + } }