From a88257efac1a222607d413c070ab4bd7dc20df3d Mon Sep 17 00:00:00 2001 From: Daniel Hensby Date: Wed, 13 Jun 2018 15:28:37 +0100 Subject: [PATCH] NEW Add version to HTTPRequest and create raw string representation --- src/Control/HTTPResponse.php | 86 ++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/src/Control/HTTPResponse.php b/src/Control/HTTPResponse.php index 987162e65..e73b97bf2 100644 --- a/src/Control/HTTPResponse.php +++ b/src/Control/HTTPResponse.php @@ -19,7 +19,7 @@ class HTTPResponse /** * @var array */ - protected static $status_codes = array( + protected static $status_codes = [ 100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK', @@ -61,20 +61,25 @@ class HTTPResponse 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', - ); + ]; /** * @var array */ - protected static $redirect_codes = array( + protected static $redirect_codes = [ 301, 302, 303, 304, 305, 307, - 308 - ); + 308, + ]; + + /** + * @var string + */ + protected $version = '1.0'; /** * @var int @@ -92,9 +97,9 @@ class HTTPResponse * @see http://en.wikipedia.org/wiki/List_of_HTTP_headers * @var array */ - protected $headers = array( + protected $headers = [ "content-type" => "text/html; charset=utf-8", - ); + ]; /** * @var string @@ -109,12 +114,31 @@ class HTTPResponse * @param string $statusDescription The text to be given alongside the status code. * See {@link setStatusCode()} for more information. */ - public function __construct($body = null, $statusCode = null, $statusDescription = null) + public function __construct($body = null, $statusCode = null, $statusDescription = null, $version = null) { $this->setBody($body); if ($statusCode) { $this->setStatusCode($statusCode, $statusDescription); } + if (!$version) { + if (preg_match('/HTTP\/(\d+(\.\d+)?)/i', $_SERVER['SERVER_PROTOCOL'], $matches)) { + $version = $matches[1]; + } + } + $this->setVersion($version); + } + + /** + * The HTTP version used to respond to this request (typically 1.0 or 1.1) + * + * @param string $version + * + * @return $this + */ + public function setVersion($version) + { + $this->version = $version; + return $this; } /** @@ -123,6 +147,7 @@ class HTTPResponse * No newlines are allowed in the description. * If omitted, will default to the standard HTTP description * for the given $code value (see {@link $status_codes}). + * * @return $this */ public function setStatusCode($code, $description = null) @@ -146,6 +171,7 @@ class HTTPResponse * Caution: Will be overwritten by {@link setStatusCode()}. * * @param string $description + * * @return $this */ public function setStatusDescription($description) @@ -154,6 +180,14 @@ class HTTPResponse return $this; } + /** + * @return string + */ + public function getVersion() + { + return $this->version; + } + /** * @return int */ @@ -167,7 +201,7 @@ class HTTPResponse */ public function getStatusDescription() { - return str_replace(array("\r","\n"), '', $this->statusDescription); + return str_replace(["\r", "\n"], '', $this->statusDescription); } /** @@ -183,11 +217,12 @@ class HTTPResponse /** * @param string $body + * * @return $this */ public function setBody($body) { - $this->body = $body ? (string) $body : $body; // Don't type-cast false-ish values, eg null is null not '' + $this->body = $body ? (string)$body : $body; // Don't type-cast false-ish values, eg null is null not '' return $this; } @@ -204,6 +239,7 @@ class HTTPResponse * * @param string $header Example: "content-type" * @param string $value Example: "text/xml" + * * @return $this */ public function addHeader($header, $value) @@ -217,6 +253,7 @@ class HTTPResponse * Return the HTTP header of the given name. * * @param string $header + * * @return string */ public function getHeader($header) @@ -241,6 +278,7 @@ class HTTPResponse * e.g. "Content-Type". * * @param string $header + * * @return $this */ public function removeHeader($header) @@ -253,6 +291,7 @@ class HTTPResponse /** * @param string $dest * @param int $code + * * @return $this */ public function redirect($dest, $code = 302) @@ -322,7 +361,7 @@ EOT ); header($method); foreach ($this->getHeaders() as $header => $value) { - header("{$header}: {$value}", true, $this->getStatusCode()); + header("{$header}: {$value}", true, $this->getStatusCode()); } } elseif ($this->getStatusCode() >= 300) { // It's critical that these status codes are sent; we need to report a failure if not. @@ -351,9 +390,9 @@ EOT /** @var HandlerInterface $handler */ $handler = Injector::inst()->get(HandlerInterface::class); $formatter = $handler->getFormatter(); - echo $formatter->format(array( - 'code' => $this->statusCode - )); + echo $formatter->format([ + 'code' => $this->statusCode, + ]); } else { echo $this->body; } @@ -379,4 +418,23 @@ EOT { return in_array($this->getStatusCode(), self::$redirect_codes); } + + /** + * The HTTP response represented as a raw string + * + * @return string + */ + public function __toString() + { + $headers = []; + foreach ($this->getHeaders() as $header => $values) { + foreach ((array)$values as $value) { + $headers[] = sprintf('%s: %s', $header, $value); + } + } + return + sprintf('HTTP/%s %s %s', $this->getVersion(), $this->getStatusCode(), $this->getStatusDescription()) . "\r\n" . + implode("\r\n", $headers) . "\r\n" . "\r\n" . + $this->getBody(); + } }