New in Symfony 4.1: HTTP header improvements
April 23, 2018 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Introduced a HeaderUtils
class
Contributed by
Christian Schmidt
in #24699.
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
Contributed by
Javier Eguiluz
in #26036.
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 */*)
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
Why '$acceptHeader->get('text/x-dvi')->getQuality();' is 1.0? I think he should match to text/*
// => 'foo=bar, baz, baz="a b c"'
Shouldn't the result be : foo=abc, bar, baz="a b c" ?