Introduced a HeaderUtils
class
Parsing HTTP headers is not as trivial as some may think. It requires parsing quoted strings with backslash escaping and ignoring white-space in certain places. We did that in some methods of the HttpFoundation component but the repeated logic was starting to make the code hard to maintain.
That's why in Symfony 4.1 we've introduced a new HeaderUtils
class that
provides the most common utilities needed when parsing HTTP headers. This is not
an internal class, so you can use it in your own code too:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
use Symfony\Component\HttpFoundation\HeaderUtils;
// Splits an HTTP header by one or more separators
HeaderUtils::split('da, en-gb;q=0.8', ',;')
// => array(array('da'), array('en-gb'), array('q', '0.8'))
// Combines an array of arrays into one associative array
HeaderUtils::combine(array(array('foo', 'abc'), array('bar')))
// => array('foo' => 'abc', 'bar' => true)
// Joins an associative array into a string for use in an HTTP header
HeaderUtils::toString(array('foo' => 'abc', 'bar' => true, 'baz' => 'a b c'), ',')
// => 'foo=abc, bar, baz="a b c"'
// Encodes a string as a quoted string, if necessary
HeaderUtils::quote('foo "bar"')
// => 'foo \"bar\"'
// Decodes a quoted string
HeaderUtils::unquote('foo \"bar\"')
// => 'foo "bar"'
Allow to bypass headers when submitting forms in tests
An issue reported by the Mink browser testing project made us realize that you cannot bypass HTTP header information when submitting forms in tests which use the BrowserKit component.
That's why in Symfony 4.1 the submit()
method now accepts a third optional
argument called $serverParameters
which allows you to do things like this:
1 2 3 4
$crawler = $client->request('GET', 'http://www.example.com/foo');
$form = $crawler->filter('input')->form();
$client->submit($form, [], ['HTTP_ACCEPT_LANGUAGE' => 'de']);
// => $client->getRequest()->getServer()['HTTP_ACCEPT_LANGUAGE'] = 'de'
Added support for default values in Accept headers
When using the Accept
HTTP header it's common to use expressions like .../*
,
*/*
and even *
to define the default values:
1
Accept: text/plain;q=0.5, text/html, text/*;q=0.8, */*
However, in Symfony versions previous to 4.1 these default values weren't supported:
1 2 3 4 5 6
use Symfony\Component\HttpFoundation\AcceptHeader;
$acceptHeader = AcceptHeader::fromString('text/plain;q=0.5, text/html, text/*;q=0.8, */*');
$quality = $acceptHeader->get('text/xml')->getQuality();
// instead of returning '0.8', this code displays the following error message:
// Call to a member function getQuality() on null
In Symfony 4.1 all these default values are now properly supported:
1 2 3 4
$acceptHeader = AcceptHeader::fromString('text/plain;q=0.5, text/html, text/*;q=0.8, */*');
$acceptHeader->get('text/xml')->getQuality(); // => 0.8 (because of text/*)
$acceptHeader->get('text/html')->getQuality(); // => 1.0
$acceptHeader->get('application/xml')->getQuality(); // => 1.0 (because of */*)
Great ! Thankx you for this tool :)
This looks really useful, thanks!
Nice, Why '$acceptHeader->get('text/x-dvi')->getQuality();' is 1.0? I think he should match to text/*
@Eugeniy you are right! I've fixed the last example. Thanks!
These are some really nice improvements! 👏
HeaderUtils::joinAssoc(array('foo' => 'abc', 'bar' => true, 'baz' => 'a b c'), ',') // => 'foo=bar, baz, baz="a b c"'
Shouldn't the result be : foo=abc, bar, baz="a b c" ?
@Thierry yes! We've fixed that and other minor errors in the post. Thank you!
Thanks to all three contributors there are really nice feature!