When to answer HTTP if-none-match and if-modified-since with HTTP 304 "Not Modified"

mychel_normandeau
mychel_normandeau used Ask the Experts™
on
I have cacheable (by proxies and clients) dynamic content made in PHP 5.1.0+.I already send the correct HTTP headers (including Last-Modified and ETag) to clients.

I now want my script to be able to answer $_SERVER['HTTP_IF_MODIFIED_SINCE'] and $_SERVER['HTTP_IF_NONE_MATCH'] when present. When the conditions matches, I want to answer with a HTTP 304 "Not Modified" to clients.

After reading tutorials, RFCs and asking questions, I've implemented a system that I want to validate. My question is: does my system is OK? Am I missing something?

(See code below)

1) The format of $_SERVER['HTTP_IF_NONE_MATCH'] can be either:

a) If-None-Match: "abc", "def", "ghi"

b) If-None-Match: "dfgjd"

and NOT:

c) If-None-Match: "abc, def, ghi"

2) As soon as one ETag in HTTP_IF_NONE_MATCH match one of the current document ETag, I issue a "304 Not Modified" even if HTTP_IF_MODIFIED_SINCE is missing or if HTTP_IF_MODIFIED_SINCE don't match the last modified date of the document.

3) If HTTP_IF_NONE_MATCH is missing but HTTP_IF_MODIFIED_SINCE is there and matching the document last modified date, I issue a "304 Not Modified".

4) To recap (using code): As soon as anyTagMatched() returns TRUE, I issue a 304. If anyTagMatched() returned NULL and isExpired() returned FALSE I can issue a 304. In any other situation I serve my page as normal (I also issue the up-to-date Last-Modified and ETag headers).
function anyTagMatched()
{
    global $currentPageETags; //array()

    $ifNoneMatch = array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) ? explode(',', $_SERVER['HTTP_IF_NONE_MATCH']) : false;
    if ($ifNoneMatch === false)
        return NULL;

    foreach ($ifNoneMatch as $currETag)
    {
        $currETag = StripQuotes(trim($currETag));
        if ($currETag != '' && in_array($currETag, $currentPageETags))
            return true;
    }

    return false;
}

function isExpired()
{
    global $currentPageLastModified;

    $ifModifiedSince = array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
    if ($ifModifiedSince === false)
        return true;
    else
        return $ifModifiedSince != $currentPageLastModified;
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

"does my system is OK? Am I missing something?"

Your system looks OK for me, and fit the logic that you already expose.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial