From ae497df6049c6b73204360d7d349ebf8942906ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9A=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=B8=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= Date: Wed, 23 Mar 2016 11:21:53 +0300 Subject: [PATCH 1/3] Single header line parsing extracted to a separate method in ResponseBuilder. --- src/Builder/ResponseBuilder.php | 70 +++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/src/Builder/ResponseBuilder.php b/src/Builder/ResponseBuilder.php index b841c03..63a43d5 100644 --- a/src/Builder/ResponseBuilder.php +++ b/src/Builder/ResponseBuilder.php @@ -48,38 +48,13 @@ public function getResponse() */ public function setHeadersFromArray(array $headers) { - $statusLine = trim(array_shift($headers)); - $parts = explode(' ', $statusLine, 3); - if (count($parts) < 2 || substr(strtolower($parts[0]), 0, 5) !== 'http/') { - throw new \UnexpectedValueException( - sprintf('"%s" is not a valid HTTP status line', $statusLine) - ); - } - - $reasonPhrase = count($parts) > 2 ? $parts[2] : ''; - $this->response = $this->response - ->withStatus((int) $parts[1], $reasonPhrase) - ->withProtocolVersion(substr($parts[0], 5)); - foreach ($headers as $headerLine) { $headerLine = trim($headerLine); if ('' === $headerLine) { continue; } - $parts = explode(':', $headerLine, 2); - if (count($parts) !== 2) { - throw new \UnexpectedValueException( - sprintf('"%s" is not a valid HTTP header line', $headerLine) - ); - } - $name = trim(urldecode($parts[0])); - $value = trim(urldecode($parts[1])); - if ($this->response->hasHeader($name)) { - $this->response = $this->response->withAddedHeader($name, $value); - } else { - $this->response = $this->response->withHeader($name, $value); - } + $this->addHeader($headerLine); } return $this; @@ -113,4 +88,47 @@ public function setHeadersFromString($headers) return $this; } + + /** + * Add header represented by a string. + * + * @param string $headerLine Response header as a string. + * + * @return $this + * + * @throws \UnexpectedValueException For invalid header values. + * @throws \InvalidArgumentException For invalid header names or values. + */ + public function addHeader($headerLine) + { + if (strpos(strtolower($headerLine), 'http/') === 0) { + $parts = explode(' ', $headerLine, 3); + if (count($parts) < 2) { + throw new \UnexpectedValueException( + sprintf('"%s" is not a valid HTTP status line', $headerLine) + ); + } + + $reasonPhrase = count($parts) > 2 ? $parts[2] : ''; + $this->response = $this->response + ->withStatus((int) $parts[1], $reasonPhrase) + ->withProtocolVersion(substr($parts[0], 5)); + } else { + $parts = explode(':', $headerLine, 2); + if (count($parts) !== 2) { + throw new \UnexpectedValueException( + sprintf('"%s" is not a valid HTTP header line', $headerLine) + ); + } + $name = trim(urldecode($parts[0])); + $value = trim(urldecode($parts[1])); + if ($this->response->hasHeader($name)) { + $this->response = $this->response->withAddedHeader($name, $value); + } else { + $this->response = $this->response->withHeader($name, $value); + } + } + + return $this; + } } From fea6e476ba434d8b9e96f87f0680bb5b97c6ba41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9A=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=B8=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= Date: Tue, 29 Mar 2016 11:09:21 +0300 Subject: [PATCH 2/3] Status line should be the first line/item in setHeadersFromString()/setHeadersFromArray(). --- src/Builder/ResponseBuilder.php | 67 ++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/Builder/ResponseBuilder.php b/src/Builder/ResponseBuilder.php index 63a43d5..4e632ad 100644 --- a/src/Builder/ResponseBuilder.php +++ b/src/Builder/ResponseBuilder.php @@ -48,6 +48,9 @@ public function getResponse() */ public function setHeadersFromArray(array $headers) { + $status = array_shift($headers); + $this->setStatus($status); + foreach ($headers as $headerLine) { $headerLine = trim($headerLine); if ('' === $headerLine) { @@ -89,6 +92,33 @@ public function setHeadersFromString($headers) return $this; } + /** + * Set response status from a status string. + * + * @param string $statusLine Response status as a string. + * + * @return $this + * + * @ throws \UnexpectedValueException For invalid header values. + * @throws \InvalidArgumentException For invalid status line. + */ + public function setStatus($statusLine) + { + $parts = explode(' ', $statusLine, 3); + if (count($parts) < 2 || strpos(strtolower($parts[0]), 'http/') !== 0) { + throw new \InvalidArgumentException( + sprintf('"%s" is not a valid HTTP status line', $statusLine) + ); + } + + $reasonPhrase = count($parts) > 2 ? $parts[2] : ''; + $this->response = $this->response + ->withStatus((int) $parts[1], $reasonPhrase) + ->withProtocolVersion(substr($parts[0], 5)); + + return $this; + } + /** * Add header represented by a string. * @@ -96,37 +126,22 @@ public function setHeadersFromString($headers) * * @return $this * - * @throws \UnexpectedValueException For invalid header values. * @throws \InvalidArgumentException For invalid header names or values. */ public function addHeader($headerLine) { - if (strpos(strtolower($headerLine), 'http/') === 0) { - $parts = explode(' ', $headerLine, 3); - if (count($parts) < 2) { - throw new \UnexpectedValueException( - sprintf('"%s" is not a valid HTTP status line', $headerLine) - ); - } - - $reasonPhrase = count($parts) > 2 ? $parts[2] : ''; - $this->response = $this->response - ->withStatus((int) $parts[1], $reasonPhrase) - ->withProtocolVersion(substr($parts[0], 5)); + $parts = explode(':', $headerLine, 2); + if (count($parts) !== 2) { + throw new \InvalidArgumentException( + sprintf('"%s" is not a valid HTTP header line', $headerLine) + ); + } + $name = trim(urldecode($parts[0])); + $value = trim(urldecode($parts[1])); + if ($this->response->hasHeader($name)) { + $this->response = $this->response->withAddedHeader($name, $value); } else { - $parts = explode(':', $headerLine, 2); - if (count($parts) !== 2) { - throw new \UnexpectedValueException( - sprintf('"%s" is not a valid HTTP header line', $headerLine) - ); - } - $name = trim(urldecode($parts[0])); - $value = trim(urldecode($parts[1])); - if ($this->response->hasHeader($name)) { - $this->response = $this->response->withAddedHeader($name, $value); - } else { - $this->response = $this->response->withHeader($name, $value); - } + $this->response = $this->response->withHeader($name, $value); } return $this; From 0d565b24b5b04fbf0a06ac46eb5fb4b2d66e9646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9A=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=B8=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= Date: Tue, 29 Mar 2016 12:25:03 +0300 Subject: [PATCH 3/3] Remove old PHPDoc tag. --- src/Builder/ResponseBuilder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Builder/ResponseBuilder.php b/src/Builder/ResponseBuilder.php index 4e632ad..0a198f4 100644 --- a/src/Builder/ResponseBuilder.php +++ b/src/Builder/ResponseBuilder.php @@ -99,7 +99,6 @@ public function setHeadersFromString($headers) * * @return $this * - * @ throws \UnexpectedValueException For invalid header values. * @throws \InvalidArgumentException For invalid status line. */ public function setStatus($statusLine)