diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d9406a68..75ee1f1dd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed +- [#140](https://github.com/zendframework/zend-http/pull/140) fixes retrieval of headers when multiple headers of the same name + are added to the `Headers` instance; it now ensures that the last header added of the same + type is retrieved when it is not a multi-value type. Previous values are overwritten. + - [#112](https://github.com/zendframework/zend-http/pull/112) provides performance improvements when parsing large chunked messages. - introduces changes to `Response::fromString()` to pull the next line of the response diff --git a/src/Headers.php b/src/Headers.php index 2986959508..e3897c1a0f 100644 --- a/src/Headers.php +++ b/src/Headers.php @@ -213,8 +213,27 @@ public function addHeaderLine($headerFieldNameOrLine, $fieldValue = null) */ public function addHeader(Header\HeaderInterface $header) { - $this->headersKeys[] = static::createKey($header->getFieldName()); - $this->headers[] = $header; + $key = static::createKey($header->getFieldName()); + $index = array_search($key, $this->headersKeys); + + // No header by that key presently; append key and header to list. + if ($index === false) { + $this->headersKeys[] = $key; + $this->headers[] = $header; + return $this; + } + + // Header exists, and is a multi-value header; append key and header to + // list (as multi-value headers are aggregated on retrieval) + $class = ($this->getPluginClassLoader()->load(str_replace('-', '', $key))) ?: Header\GenericHeader::class; + if (in_array(Header\MultipleHeaderInterface::class, class_implements($class, true))) { + $this->headersKeys[] = $key; + $this->headers[] = $header; + return $this; + } + + // Otherwise, we replace the current instance. + $this->headers[$index] = $header; return $this; } @@ -286,6 +305,7 @@ public function get($name) if (is_array($this->headers[$index])) { return $this->lazyLoadHeader($index); } + return $this->headers[$index]; } diff --git a/test/HeadersTest.php b/test/HeadersTest.php index 603c5dc51a..7437d5ecf4 100644 --- a/test/HeadersTest.php +++ b/test/HeadersTest.php @@ -119,6 +119,17 @@ public function testHeadersHasAndGetWorkProperly() $this->assertSame($f, $headers->get('foo')); } + public function testHeadersGetReturnsLastAddedHeaderValue() + { + $headers = new Headers(); + $headers->addHeaders([ + new Header\GenericHeader('Foo', 'bar'), + ]); + $headers->addHeader(new Header\GenericHeader('Foo', $value = 'baz')); + + $this->assertEquals($value, $headers->get('foo')->getFieldValue()); + } + public function testHeadersAggregatesHeaderObjects() { $fakeHeader = new Header\GenericHeader('Fake', 'bar');