Skip to content

Commit

Permalink
Fixing CakeRequest::accepts() where ;q values on Accept header
Browse files Browse the repository at this point in the history
were not respected.
Fixes #1940
  • Loading branch information
markstory committed Aug 27, 2011
1 parent 5df12a2 commit 1a872e6
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
28 changes: 20 additions & 8 deletions lib/Cake/Network/CakeRequest.php
Expand Up @@ -605,23 +605,35 @@ public function subdomains($tldLength = 1) {
*
* `$this->request->accepts('json');`
*
* This method will order the returned content types by the preference values indicated
* by the client.
*
* @param string $type The content type to check for. Leave null to get all types a client accepts.
* @return mixed Either an array of all the types the client accepts or a boolean if they accept the
* provided type.
*/
public function accepts($type = null) {
$acceptTypes = explode(',', $this->header('accept'));
$acceptTypes = array_map('trim', $acceptTypes);
foreach ($acceptTypes as $i => $accepted) {
if (strpos($accepted, ';') !== false) {
list($accepted) = explode(';', $accepted);
$acceptTypes[$i] = $accepted;
$accept = array();
$header = explode(',', $this->header('accept'));
foreach (array_filter(array_reverse($header)) as $value) {
$prefPos = strpos($value, ';');
if ($prefPos !== false) {
$prefValue = (float) substr($value, strpos($value, '=') + 1);
$value = trim(substr($value, 0, $prefPos));
} else {
$prefValue = 1.0;
$value = trim($value);
}
if ($prefValue) {
$accept[$value] = $prefValue;
}
}
arsort($accept);
$accept = array_keys($accept);
if ($type === null) {
return $acceptTypes;
return $accept;
}
return in_array($type, $acceptTypes);
return in_array($type, $accept);
}

/**
Expand Down
15 changes: 14 additions & 1 deletion lib/Cake/Test/Case/Network/CakeRequestTest.php
Expand Up @@ -785,7 +785,7 @@ public function testAccepts() {

$result = $request->accepts();
$expected = array(
'text/xml', 'application/xml', 'application/xhtml+xml', 'text/html', 'text/plain', 'image/png'
'text/xml', 'application/xhtml+xml', 'text/html', 'image/png', 'text/plain', 'application/xml'
);
$this->assertEquals($expected, $result, 'Content types differ.');

Expand Down Expand Up @@ -813,6 +813,19 @@ public function testAcceptWithWhitespace() {
$this->assertTrue($request->accepts('text/html'));
}

/**
* Content types from accepts() should respect the client's q preference values.
*
* @return void
*/
public function testAcceptWithQvalueSorting() {
$_SERVER['HTTP_ACCEPT'] = 'text/html;q=0.8,application/json;q=0.7,application/xml;q=1.0';
$request = new CakeRequest('/', false);
$result = $request->accepts();
$expected = array('application/xml', 'text/html', 'application/json');
$this->assertEquals($expected, $result);
}

/**
* testBaseUrlAndWebrootWithModRewrite method
*
Expand Down

0 comments on commit 1a872e6

Please sign in to comment.