private function checkPreconditions(Request $request, int $mtime, string $etag)
{
$ifMatch = $request->getHeader("If-Match");
if ($ifMatch && \stripos($ifMatch, $etag) === false) {
return self::PRECOND_FAILED;
}
$ifNoneMatch = $request->getHeader("If-None-Match");
if ($ifNoneMatch && \stripos($ifNoneMatch, $etag) !== false) {
return self::PRECOND_NOT_MODIFIED;
}
$ifModifiedSince = $request->getHeader("If-Modified-Since");
$ifModifiedSince = $ifModifiedSince ? @\strtotime($ifModifiedSince) : 0;
if ($ifModifiedSince && $mtime > $ifModifiedSince) {
return self::PRECOND_NOT_MODIFIED;
}
$ifUnmodifiedSince = $request->getHeader("If-Unmodified-Since");
$ifUnmodifiedSince = $ifUnmodifiedSince ? @\strtotime($ifUnmodifiedSince) : 0;
if ($ifUnmodifiedSince && $mtime > $ifUnmodifiedSince) {
return self::PRECOND_FAILED;
}
$ifRange = $request->getHeader("If-Range");
if ($ifRange === null || !$request->getHeader("Range")) {
return self::PRECOND_OK;
}
/**
* This is a really stupid feature of HTTP but ...
* If-Range headers may be either an HTTP timestamp or an Etag:
*
* If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
*
* @link https://tools.ietf.org/html/rfc7233#section-3.2
*/
if ($httpDate = @\strtotime($ifRange)) {
return $httpDate > $mtime ? self::PRECOND_IF_RANGE_OK : self::PRECOND_IF_RANGE_FAILED;
}
// If the If-Range header was not an HTTP date we assume it's an Etag
return $etag === $ifRange ? self::PRECOND_IF_RANGE_OK : self::PRECOND_IF_RANGE_FAILED;
}