Nyholm / psr7

A super lightweight PSR-7 implementation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Headers with multiple values should only be separated by a comma

adriansuter opened this issue · comments

Hi all

The PSR7-specification (see PR php-fig/fig-standards#1194) as well as the RFC 2616 define a comma, not a comma with white-space, as separator.

We should probably update the following method:

public function getHeaderLine($header): string
{
return \implode(', ', $this->getHeader($header));
}

I do not believe the PHP-FIG is solving this correctly, and I should probably post about it on the mailing list. Trying to convince all libraries to change their behaviour (if it is true that they all went with , as a separator) sounds like a much harder job than them updating the standard to read “concatenated with a comma and space character”.

[…] as well as the RFC 2616 define a comma […]

PSR-7 is not based on RFC 2616, but on RFC 7230. This is nice because RFC 7230 gives us an ABNF for lists of multiple values: 1#element => element *( OWS "," OWS element ) as well as “valid values for example-list”:

foo,bar
foo ,bar,
foo , ,bar,charlie

Clearly optional whitespace (OWS) is allowed here. The question is whether it matters that we as a library add a single space of extra optional whitespace, I personally prefer my library to handle this for readability. YMMV.

Although RFC 2616 does not seem to include a similar ABNF, I still am having a hard time to figure out based on what section the space character isn’t allowed. The following is mentioned in section 4.2 on Message Headers:

Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)].

As I said, it doesn’t seem to provide a specification for #(values) but it does provide examples for almost every one of its uses. The first use of the #( syntax is for the Accept header where it defines:

       Accept         = "Accept" ":"
                        #( media-range [ accept-params ] )

Their own example of a multi-media-range Accept header with comma separation follows in the same section:

The example

    Accept: audio/*; q=0.2, audio/basic

So even RFC 2616 adds an extra space after the comma.

If the PSR-7 spec really is deviating from the HTTP specification, please point out where, because that would make it a much more serious issue than I thought!

Unfortunately we do have both implementations.

Without white-space:

With white-space:

So, I guess the PSR7 specification should mention that OWS.

Oh, this is super interesting.

Thank you for all the references. Im honestly not sure what the best solution here is.

@Tobion, what do you think? Should Guzzle/psr7 and Nyholm/psr7 remove the space or is it something we dont care about?

Since both are valid in terms of the http spec, there is no need to change anything IMO. The psr-7 spec is just not precise enough.