-
Notifications
You must be signed in to change notification settings - Fork 152
Header's improvements #161
Header's improvements #161
Conversation
* @dataProvider testNumericHeaderValues | ||
* @group 99 | ||
*/ | ||
public function testFilterHeadersShouldAllowIntegersAndFloats($value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about removal of this test case, particularly as it was solving a reported issue. Can you reinstate it or rewrite it to test against the current changes, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tried, but there is some exclusive cases. Look at invalidHeaderValues
. There are int and float as invalid value. This removed tests uses testNumericHeaderValues
where is also int and float but as valid value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This goes to another comment I've made in the review: numeric values should be allowed, which is what #99 was reporting. Internally, we can convert those to strings, so that the return values of getHeaders()
, getHeader()
, and getHeaderLine()
are consistent with the spec. But we must allow them; requiring developers to cast those values to strings manually before calling withHeader()
is a BC break, and poor for usability.
This test will likely need to be rewritten, but the behavior we're testing is the same: numeric values should be valid for header values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the work you've done here, as it does greatly simplify much of the code. The big issue I have is with treatment of numeric values for header values. As noted, numeric values are often used (e.g., Content-Length
, X-Page-Offset
, etc.), and should be accepted as valid input. However, with the changes made, such values are immediately considered invalid, which is a BC break. Admittedly, we had some problematic code previously, as providing an array of values would raise an exception if any of those values were not strings; that situation, however, should be fixed.
Are you still willing to make the requested changes, @snapshotpl ?
@@ -112,7 +112,7 @@ public function getHeaders() | |||
*/ | |||
public function hasHeader($header) | |||
{ | |||
return array_key_exists(strtolower($header), $this->headerNames); | |||
return isset($this->headerNames[strtolower($header)]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original was more correct.
The ABNS for header values is:
field-value = *( field-content / obs-fold )
The above means zero or more of valid field content/folded content. In other words, you can have a header with no value associated with it.
Since isset()
will return false
on an empty string, empty array, or null value, the above would result in a false negative in the case of a header being present with no value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added test for that - still working as expected (testHeaderExistsIfWithNoValues
, testHeaderWithNoValues
). Do you have any other test case to fall it?
@@ -129,6 +129,12 @@ public static function isValid($value) | |||
*/ | |||
public static function assertValid($value) | |||
{ | |||
if (! is_string($value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is somewhat problematic. Numeric values are allowed in headers — e.g., Content-Length — which means asserting that the value is a string could lead to issues for existing users (including those using the SapiStreamEmitter
).
That said, we currently enforce this when an array of header values is passed to withHeader()
(via the private arrayContainsOnlyStrings()
method).
My feeling is that we should likely cast numeric values to strings when storing headers, vs. throwing them out outright. This would, of course, necessitate further changes from what you were already planning to introduce in this pull request.
list($this->headerNames, $headers) = $this->filterHeaders($headers); | ||
$this->assertHeaders($headers); | ||
$this->headers = $headers; | ||
$this->setHeaders($headers); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assumes setHeaders()
is in the class composing the trait; the trait should define an abstract method, to ensure that the functionality can work. (This should likely be done for the other calls on $this
as well.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done by use MessageTrait. No magic anymore!
@@ -218,7 +218,7 @@ public function testWithHeaderReplacesDifferentCapitalization() | |||
*/ | |||
public function testWithAddedHeaderRaisesExceptionForNonStringNonArrayValue($value) | |||
{ | |||
$this->setExpectedException('InvalidArgumentException', 'must be a string'); | |||
$this->setExpectedException('InvalidArgumentException', 'expected string'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this exception message different?
@@ -353,7 +328,7 @@ public function invalidArrayHeaderValues() | |||
*/ | |||
public function testFilterHeadersShouldRaiseExceptionForInvalidHeaderValuesInArrays($value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename the method to s/FilterHeaders/SetHeaders/
@@ -368,7 +343,7 @@ public function testFilterHeadersShouldRaiseExceptionForInvalidHeaderValuesInArr | |||
*/ | |||
public function testFilterHeadersShouldRaiseExceptionForInvalidHeaderScalarValues($value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename the method to s/FilterHeaders/SetHeaders/
@@ -129,6 +129,12 @@ public static function isValid($value) | |||
*/ | |||
public static function assertValid($value) | |||
{ | |||
if (! is_string($value) && ! is_numeric($value)) { | |||
throw new InvalidArgumentException(sprintf( | |||
'Invalid header value type; must be a string, numeric or array; received %s', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
array
is not allowed on this current logic
Thanks, @snapshotpl |
I remove duplicates and simplify some parts of code