[http-foudation] Better accept header parsing
This commit is contained in:
parent
d8f6021fc1
commit
6b601bd9a6
22
UPGRADE-2.2.md
Normal file
22
UPGRADE-2.2.md
Normal file
@ -0,0 +1,22 @@
|
||||
UPGRADE FROM 2.1 to 2.2
|
||||
=======================
|
||||
|
||||
#### Deprecations
|
||||
|
||||
* The `Request::splitHttpAcceptHeader()` is deprecated and will be removed in 2.3.
|
||||
|
||||
You should now use the `AcceptHeader` class which give you fluent methods to
|
||||
parse request accept-* headers. Some examples:
|
||||
|
||||
```
|
||||
$accept = AcceptHeader::fromString($request->headers->get('Accept'));
|
||||
if ($accept->has('text/html') {
|
||||
$item = $accept->get('html');
|
||||
$charset = $item->getAttribute('charset', 'utf-8');
|
||||
$quality = $item->getQuality();
|
||||
}
|
||||
|
||||
// accepts items are sorted by descending quality
|
||||
$accepts = AcceptHeader::fromString($request->headers->get('Accept'))->all();
|
||||
|
||||
```
|
172
src/Symfony/Component/HttpFoundation/AcceptHeader.php
Normal file
172
src/Symfony/Component/HttpFoundation/AcceptHeader.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
/**
|
||||
* Represents an Accept-* header.
|
||||
*
|
||||
* An accept header is compound with a list of items,
|
||||
* sorted by descending quality.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*/
|
||||
class AcceptHeader
|
||||
{
|
||||
/**
|
||||
* @var AcceptHeaderItem[]
|
||||
*/
|
||||
private $items = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $sorted = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param AcceptHeaderItem[] $items
|
||||
*/
|
||||
public function __construct(array $items)
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
$this->add($item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an AcceptHeader instance from a string.
|
||||
*
|
||||
* @param string $headerValue
|
||||
*
|
||||
* @return AcceptHeader
|
||||
*/
|
||||
public static function fromString($headerValue)
|
||||
{
|
||||
$index = 0;
|
||||
|
||||
return new self(array_map(function ($itemValue) use (&$index) {
|
||||
$item = AcceptHeaderItem::fromString($itemValue);
|
||||
$item->setIndex($index++);
|
||||
|
||||
return $item;
|
||||
}, preg_split('/\s*(?:,*("[^"]+"),*|,*(\'[^\']+\'),*|,+)\s*/', $headerValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns header value's string representation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return implode(',', $this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if header has given value.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function has($value)
|
||||
{
|
||||
return isset($this->items[$value]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given value's item, if exists.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return AcceptHeaderItem|null
|
||||
*/
|
||||
public function get($value)
|
||||
{
|
||||
return isset($this->items[$value]) ? $this->items[$value] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item.
|
||||
*
|
||||
* @param AcceptHeaderItem $item
|
||||
*
|
||||
* @return AcceptHeader
|
||||
*/
|
||||
public function add(AcceptHeaderItem $item)
|
||||
{
|
||||
$this->items[$item->getValue()] = $item;
|
||||
$this->sorted = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all items.
|
||||
*
|
||||
* @return AcceptHeaderItem[]
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$this->sort();
|
||||
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters items on their value using given regex.
|
||||
*
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return AcceptHeader
|
||||
*/
|
||||
public function filter($pattern)
|
||||
{
|
||||
return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) {
|
||||
return preg_match($pattern, $item->getValue());
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first item.
|
||||
*
|
||||
* @return AcceptHeaderItem|null
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
$this->sort();
|
||||
|
||||
return !empty($this->items) ? current($this->items) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts items by descending quality
|
||||
*/
|
||||
private function sort()
|
||||
{
|
||||
if (!$this->sorted) {
|
||||
uasort($this->items, function ($a, $b) {
|
||||
$qA = $a->getQuality();
|
||||
$qB = $b->getQuality();
|
||||
|
||||
if ($qA === $qB) {
|
||||
return $a->getIndex() > $b->getIndex() ? 1 : -1;
|
||||
}
|
||||
|
||||
return $qA > $qB ? -1 : 1;
|
||||
});
|
||||
|
||||
$this->sorted = true;
|
||||
}
|
||||
}
|
||||
}
|
226
src/Symfony/Component/HttpFoundation/AcceptHeaderItem.php
Normal file
226
src/Symfony/Component/HttpFoundation/AcceptHeaderItem.php
Normal file
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
/**
|
||||
* Represents an Accept-* header item.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*/
|
||||
class AcceptHeaderItem
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $quality = 1.0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $index = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $attributes = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct($value, array $attributes = array())
|
||||
{
|
||||
$this->value = $value;
|
||||
foreach ($attributes as $name => $value) {
|
||||
$this->setAttribute($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an AcceptHeaderInstance instance from a string.
|
||||
*
|
||||
* @param string $itemValue
|
||||
*
|
||||
* @return AcceptHeaderItem
|
||||
*/
|
||||
public static function fromString($itemValue)
|
||||
{
|
||||
$bits = preg_split('/\s*(?:;*("[^"]+");*|;*(\'[^\']+\');*|;+)\s*/', $itemValue, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
$value = array_shift($bits);
|
||||
$attributes = array();
|
||||
|
||||
$lastNullAttribute = null;
|
||||
foreach ($bits as $bit) {
|
||||
if (($start = substr($bit, 0, 1)) === ($end = substr($bit, -1)) && ($start === '"' || $start === '\'')) {
|
||||
$attributes[$lastNullAttribute] = substr($bit, 1, -1);
|
||||
} elseif ('=' === $end) {
|
||||
$lastNullAttribute = $bit = substr($bit, 0, -1);
|
||||
$attributes[$bit] = null;
|
||||
} else {
|
||||
$parts = explode('=', $bit);
|
||||
$attributes[$parts[0]] = isset($parts[1]) && strlen($parts[1]) > 0 ? $parts[1] : '';
|
||||
}
|
||||
}
|
||||
|
||||
return new self(($start = substr($value, 0, 1)) === ($end = substr($value, -1)) && ($start === '"' || $start === '\'') ? substr($value, 1, -1) : $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns header value's string representation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$string = $this->value.($this->quality < 1 ? ';q='.$this->quality : '');
|
||||
if (count($this->attributes) > 0) {
|
||||
$string .= ';'.implode(';', array_map(function($name, $value) {
|
||||
return sprintf(preg_match('/[,;=]/', $value) ? '%s="%s"' : '%s=%s', $name, $value);
|
||||
}, array_keys($this->attributes), $this->attributes));
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item value.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return AcceptHeaderItem
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item quality.
|
||||
*
|
||||
* @param float $quality
|
||||
*
|
||||
* @return AcceptHeaderItem
|
||||
*/
|
||||
public function setQuality($quality)
|
||||
{
|
||||
$this->quality = $quality;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item quality.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getQuality()
|
||||
{
|
||||
return $this->quality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item index.
|
||||
*
|
||||
* @param int $index
|
||||
*
|
||||
* @return AcceptHeaderItem
|
||||
*/
|
||||
public function setIndex($index)
|
||||
{
|
||||
$this->index = $index;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item index.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if an attribute exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasAttribute($name)
|
||||
{
|
||||
return isset($this->attributes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an attribute by its name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all attributes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an attribute.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*
|
||||
* @return AcceptHeaderItem
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
if ('q' === $name) {
|
||||
$this->quality = (float) $value;
|
||||
} else {
|
||||
$this->attributes[$name] = (string) $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.2.0
|
||||
-----
|
||||
|
||||
* Request::splitHttpAcceptHeader() method is deprecated and will be removed in 2.3
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
|
@ -1187,9 +1187,9 @@ class Request
|
||||
return $this->languages;
|
||||
}
|
||||
|
||||
$languages = $this->splitHttpAcceptHeader($this->headers->get('Accept-Language'));
|
||||
$languages = AcceptHeader::fromString($this->headers->get('Accept-Language'))->all();
|
||||
$this->languages = array();
|
||||
foreach ($languages as $lang => $q) {
|
||||
foreach (array_keys($languages) as $lang) {
|
||||
if (strstr($lang, '-')) {
|
||||
$codes = explode('-', $lang);
|
||||
if ($codes[0] == 'i') {
|
||||
@ -1229,7 +1229,7 @@ class Request
|
||||
return $this->charsets;
|
||||
}
|
||||
|
||||
return $this->charsets = array_keys($this->splitHttpAcceptHeader($this->headers->get('Accept-Charset')));
|
||||
return $this->charsets = array_keys(AcceptHeader::fromString($this->headers->get('Accept-Charset'))->all());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1245,7 +1245,7 @@ class Request
|
||||
return $this->acceptableContentTypes;
|
||||
}
|
||||
|
||||
return $this->acceptableContentTypes = array_keys($this->splitHttpAcceptHeader($this->headers->get('Accept')));
|
||||
return $this->acceptableContentTypes = array_keys(AcceptHeader::fromString($this->headers->get('Accept'))->all());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1269,40 +1269,21 @@ class Request
|
||||
* @param string $header Header to split
|
||||
*
|
||||
* @return array Array indexed by the values of the Accept-* header in preferred order
|
||||
*
|
||||
* @deprecated Deprecated since version 2.2, to be removed in 2.3.
|
||||
*/
|
||||
public function splitHttpAcceptHeader($header)
|
||||
{
|
||||
if (!$header) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$values = array();
|
||||
$groups = array();
|
||||
foreach (array_filter(explode(',', $header)) as $value) {
|
||||
// Cut off any q-value that might come after a semi-colon
|
||||
if (preg_match('/;\s*(q=.*$)/', $value, $match)) {
|
||||
$q = substr(trim($match[1]), 2);
|
||||
$value = trim(substr($value, 0, -strlen($match[0])));
|
||||
} else {
|
||||
$q = 1;
|
||||
$headers = array();
|
||||
foreach (AcceptHeader::fromString($header)->all() as $item) {
|
||||
$key = $item->getValue();
|
||||
foreach ($item->getAttributes() as $name => $value) {
|
||||
$key .= sprintf(';%s=%s', $name, $value);
|
||||
}
|
||||
|
||||
$groups[$q][] = $value;
|
||||
$headers[$key] = $item->getQuality();
|
||||
}
|
||||
|
||||
krsort($groups);
|
||||
|
||||
foreach ($groups as $q => $items) {
|
||||
$q = (float) $q;
|
||||
|
||||
if (0 < $q) {
|
||||
foreach ($items as $value) {
|
||||
$values[trim($value)] = $q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation\Tests;
|
||||
|
||||
use Symfony\Component\HttpFoundation\AcceptHeaderItem;
|
||||
|
||||
class AcceptHeaderItemTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFromStringData
|
||||
*/
|
||||
public function testFromString($string, $value, array $attributes)
|
||||
{
|
||||
$item = AcceptHeaderItem::fromString($string);
|
||||
$this->assertEquals($value, $item->getValue());
|
||||
$this->assertEquals($attributes, $item->getAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideToStringData
|
||||
*/
|
||||
public function testToString($value, array $attributes, $string)
|
||||
{
|
||||
$item = new AcceptHeaderItem($value, $attributes);
|
||||
$this->assertEquals($string, (string) $item);
|
||||
}
|
||||
|
||||
public function testValue()
|
||||
{
|
||||
$item = new AcceptHeaderItem('value', array());
|
||||
$this->assertEquals('value', $item->getValue());
|
||||
|
||||
$item->setValue('new value');
|
||||
$this->assertEquals('new value', $item->getValue());
|
||||
|
||||
$item->setValue(1);
|
||||
$this->assertEquals('1', $item->getValue());
|
||||
}
|
||||
|
||||
public function testQuality()
|
||||
{
|
||||
$item = new AcceptHeaderItem('value', array());
|
||||
$this->assertEquals(1.0, $item->getQuality());
|
||||
|
||||
$item->setQuality(0.5);
|
||||
$this->assertEquals(0.5, $item->getQuality());
|
||||
|
||||
$item->setAttribute('q', 0.75);
|
||||
$this->assertEquals(0.75, $item->getQuality());
|
||||
$this->assertFalse($item->hasAttribute('q'));
|
||||
}
|
||||
|
||||
public function testAttribute()
|
||||
{
|
||||
$item = new AcceptHeaderItem('value', array());
|
||||
$this->assertEquals(array(), $item->getAttributes());
|
||||
$this->assertFalse($item->hasAttribute('test'));
|
||||
$this->assertNull($item->getAttribute('test'));
|
||||
$this->assertEquals('default', $item->getAttribute('test', 'default'));
|
||||
|
||||
$item->setAttribute('test', 'value');
|
||||
$this->assertEquals(array('test' => 'value'), $item->getAttributes());
|
||||
$this->assertTrue($item->hasAttribute('test'));
|
||||
$this->assertEquals('value', $item->getAttribute('test'));
|
||||
$this->assertEquals('value', $item->getAttribute('test', 'default'));
|
||||
}
|
||||
|
||||
public function provideFromStringData()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'text/html',
|
||||
'text/html', array()
|
||||
),
|
||||
array(
|
||||
'"this;should,not=matter"',
|
||||
'this;should,not=matter', array()
|
||||
),
|
||||
array(
|
||||
"text/plain; charset=utf-8;param=\"this;should,not=matter\";\tfootnotes=true",
|
||||
'text/plain', array('charset' => 'utf-8', 'param' => 'this;should,not=matter', 'footnotes' => 'true')
|
||||
),
|
||||
array(
|
||||
'"this;should,not=matter";charset=utf-8',
|
||||
'this;should,not=matter', array('charset' => 'utf-8')
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function provideToStringData()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'text/html', array(),
|
||||
'text/html'
|
||||
),
|
||||
array(
|
||||
'text/plain', array('charset' => 'utf-8', 'param' => 'this;should,not=matter', 'footnotes' => 'true'),
|
||||
'text/plain;charset=utf-8;param="this;should,not=matter";footnotes=true'
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpFoundation\Tests;
|
||||
|
||||
use Symfony\Component\HttpFoundation\AcceptHeader;
|
||||
use Symfony\Component\HttpFoundation\AcceptHeaderItem;
|
||||
|
||||
class AcceptHeaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideFromStringData
|
||||
*/
|
||||
public function testFromString($string, array $items)
|
||||
{
|
||||
$header = AcceptHeader::fromString($string);
|
||||
$parsed = array_values($header->all());
|
||||
// reset index since the fixtures don't have them set
|
||||
foreach ($parsed as $item) {
|
||||
$item->setIndex(0);
|
||||
}
|
||||
$this->assertEquals($items, $parsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideToStringData
|
||||
*/
|
||||
public function testToString(array $items, $string)
|
||||
{
|
||||
$header = new AcceptHeader($items);
|
||||
$this->assertEquals($string, (string) $header);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideFilterData
|
||||
*/
|
||||
public function testFilter($string, $filter, array $values)
|
||||
{
|
||||
$header = AcceptHeader::fromString($string)->filter($filter);
|
||||
$this->assertEquals($values, array_keys($header->all()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideSortingData
|
||||
*/
|
||||
public function testSorting($string, array $values)
|
||||
{
|
||||
$header = AcceptHeader::fromString($string);
|
||||
$this->assertEquals($values, array_keys($header->all()));
|
||||
}
|
||||
|
||||
public function provideFromStringData()
|
||||
{
|
||||
return array(
|
||||
array('', array()),
|
||||
array('gzip', array(new AcceptHeaderItem('gzip'))),
|
||||
array('gzip,deflate,sdch', array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch'))),
|
||||
array("gzip, deflate\t,sdch", array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch'))),
|
||||
array('"this;should,not=matter"', array(new AcceptHeaderItem('this;should,not=matter'))),
|
||||
);
|
||||
}
|
||||
|
||||
public function provideFilterData()
|
||||
{
|
||||
return array(
|
||||
array('fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4', '/fr.*/', array('fr-FR', 'fr')),
|
||||
);
|
||||
}
|
||||
|
||||
public function provideSortingData()
|
||||
{
|
||||
return array(
|
||||
'quality has priority' => array('*;q=0.3,ISO-8859-1,utf-8;q=0.7', array('ISO-8859-1', 'utf-8', '*')),
|
||||
'order matters when q is equal' => array('*;q=0.3,ISO-8859-1;q=0.7,utf-8;q=0.7', array('ISO-8859-1', 'utf-8', '*')),
|
||||
'order matters when q is equal2' => array('*;q=0.3,utf-8;q=0.7,ISO-8859-1;q=0.7', array('utf-8', 'ISO-8859-1', '*')),
|
||||
);
|
||||
}
|
||||
|
||||
public function provideToStringData()
|
||||
{
|
||||
return array(
|
||||
array(array(), ''),
|
||||
array(array(new AcceptHeaderItem('gzip')), 'gzip'),
|
||||
array(array(new AcceptHeaderItem('gzip'), new AcceptHeaderItem('deflate'), new AcceptHeaderItem('sdch')), 'gzip,deflate,sdch'),
|
||||
array(array(new AcceptHeaderItem('this;should,not=matter')), 'this;should,not=matter'),
|
||||
);
|
||||
}
|
||||
}
|
@ -1026,10 +1026,10 @@ class RequestTest extends \PHPUnit_Framework_TestCase
|
||||
array('text/html;q=0.8', array('text/html' => 0.8)),
|
||||
array('text/html;foo=bar;q=0.8 ', array('text/html;foo=bar' => 0.8)),
|
||||
array('text/html;charset=utf-8; q=0.8', array('text/html;charset=utf-8' => 0.8)),
|
||||
array('text/html,application/xml;q=0.9,*/*;charset=utf-8; q=0.8', array('text/html' => 1, 'application/xml' => 0.9, '*/*;charset=utf-8' => 0.8)),
|
||||
array('text/html,application/xhtml+xml;q=0.9,*/*;q=0.8; foo=bar', array('text/html' => 1, 'application/xhtml+xml' => 0.9, '*/*' => 0.8)),
|
||||
array('text/html,application/xhtml+xml;charset=utf-8;q=0.9; foo=bar,*/*', array('text/html' => 1, '*/*' => 1, 'application/xhtml+xml;charset=utf-8' => 0.9)),
|
||||
array('text/html,application/xhtml+xml', array('application/xhtml+xml' => 1, 'text/html' => 1)),
|
||||
array('text/html,application/xml;q=0.9,*/*;charset=utf-8; q=0.8', array('text/html' => 1.0, 'application/xml' => 0.9, '*/*;charset=utf-8' => 0.8)),
|
||||
array('text/html,application/xhtml+xml;q=0.9,*/*;q=0.8; foo=bar', array('text/html' => 1.0, 'application/xhtml+xml' => 0.9, '*/*;foo=bar' => 0.8)),
|
||||
array('text/html,application/xhtml+xml;charset=utf-8;q=0.9; foo=bar,*/*', array('text/html' => 1.0, '*/*' => 1.0, 'application/xhtml+xml;charset=utf-8;foo=bar' => 0.9)),
|
||||
array('text/html,application/xhtml+xml', array('text/html' => 1.0, 'application/xhtml+xml' => 1.0)),
|
||||
);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user