Skip to content
This repository has been archived by the owner on May 13, 2021. It is now read-only.

Commit

Permalink
Implement weak comparisons
Browse files Browse the repository at this point in the history
  • Loading branch information
micheh committed Apr 15, 2016
1 parent f3215d5 commit b99e8ae
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
31 changes: 21 additions & 10 deletions src/CacheUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,9 @@ public function hasStateValidator(RequestInterface $request)
*/
public function hasCurrentState(RequestInterface $request, $eTag, $lastModified = null)
{
if ($eTag) {
$eTag = '"' . trim($eTag, '"') . '"';
}

$ifMatch = $request->getHeaderLine('If-Match');
if ($ifMatch) {
if (!$this->matchesETag($eTag, $ifMatch)) {
if (!$this->matchesETag($eTag, $ifMatch, false)) {
return false;
}
} else {
Expand All @@ -238,7 +234,7 @@ public function hasCurrentState(RequestInterface $request, $eTag, $lastModified
}

$ifNoneMatch = $request->getHeaderLine('If-None-Match');
if ($ifNoneMatch && $this->matchesETag($eTag, $ifNoneMatch)) {
if ($ifNoneMatch && $this->matchesETag($eTag, $ifNoneMatch, true)) {
return false;
}

Expand All @@ -265,7 +261,7 @@ public function isNotModified(RequestInterface $request, ResponseInterface $resp
{
$noneMatch = $request->getHeaderLine('If-None-Match');
if ($noneMatch) {
return $this->matchesETag($response->getHeaderLine('ETag'), $noneMatch);
return $this->matchesETag($response->getHeaderLine('ETag'), $noneMatch, true);
}

if (!in_array($request->getMethod(), ['GET', 'HEAD'], true)) {
Expand Down Expand Up @@ -459,16 +455,31 @@ protected function getCacheControl(ResponseInterface $response)
*
* @param string $currentETag The current ETag
* @param string $requestETags The ETags from the request
* @param bool $weak Whether to do a weak comparison (default: strong)
* @return bool True if the current ETag matches the ETags of the request, false otherwise
*/
private function matchesETag($currentETag, $requestETags)
private function matchesETag($currentETag, $requestETags, $weak = false)
{
if ($requestETags === '*') {
return (bool) $currentETag;
}

// TODO Add weak and strong comparison
return in_array($currentETag, preg_split('/\s*,\s*/', $requestETags), true);
if (strpos($currentETag, 'W/"') === 0) {
if (!$weak) {
return false;
}
} else {
$currentETag = '"' . trim($currentETag, '"') . '"';
}

$eTags = preg_split('/\s*,\s*/', $requestETags);
$match = in_array($currentETag, $eTags, true);
if (!$match && $weak) {
$other = strpos($currentETag, '"') === 0 ? 'W/' . $currentETag : substr($currentETag, 2);
$match = in_array($other, $eTags, true);
}

return $match;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions test/CacheUtilTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,9 @@ public function currentStateETags()
'not-current-multiple' => ['"foo", "bar"', 'baz', false],
'star' => ['*', 'baz', true],
'star-without-current' => ['*', null, false],
'weak-client' => ['W/"foo"', 'foo', false],
'weak-server' => ['"foo"', 'W/"foo"', false],
'weak-both' => ['W/"foo"', 'W/"foo"', false],
];
}

Expand Down Expand Up @@ -405,6 +408,9 @@ public function notModifiedETags()
'star' => ['*', '"foo"', true],
'star-without-current' => ['*', '', false],
'not-modified-multiple-no-space' => ['"foo","bar"', '"bar"', true],
'weak-client' => ['W/"foo"', '"foo"', true],
'weak-server' => ['"foo"', 'W/"foo"', true],
'weak-both' => ['W/"foo"', 'W/"foo"', true],
];
}

Expand Down

0 comments on commit b99e8ae

Please sign in to comment.