HTTP if-none-match и if-modified-Since и уточнение 304 в PHP

У меня вопрос о том, как ответить на HTTP 304 «Не изменено», когда я получаю оба if-none-match и if-modified-Since из запроса прокси / клиента.

Из раздела 14.26 RFC 2616 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26):

Если ни один из тегов объекта не совпадает, то сервер МОЖЕТ выполнить запрошенный метод, как если бы поле заголовка If-None-Match не существовало, но ДОЛЖЕН также игнорировать любые поля заголовка If-Modified-Since в запросе. То есть, если ни один тег объекта не совпадает, сервер НЕ ДОЛЖЕН возвращать ответ 304 (Not Modified).

Я не уверен, что понимаю это утверждение ...

  1. «Если ни один из тегов объекта не совпадает» в PHP, говорят ли они о $_SERVER['HTTP_IF_NONE_MATCH'] по сравнению с моими ETags, которые я отправил ранее?
  2. Если я правильно понимаю это утверждение, как только ни один из ETag, перечисленных в $_SERVER['HTTP_IF_NONE_MATCH'], не соответствует моим ETags, я прекращаю все проверки и обслуживаю страницу в обычном режиме.

Кто-нибудь может перевести эту RFC-часть в псевдокод (или PHP-код) и / или ответить на мои 2 пункта выше?

РЕДАКТИРОВАТЬ 1: Спасибо, Святой Воланд, за ваш ответ. Можете ли вы (или кто-либо другой) сказать мне, прав ли я по этим 6 пунктам:

  1. Формат $_SERVER['HTTP_IF_NONE_MATCH'] может быть любым:

    a) Если-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"

    б) Если-None-Match: "xyzzy"

    и НЕ:

    c) Если-None-Match: "xyzzy, r2d2xxxx, c3piozzzz"

  2. Если !array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER), anyTagMatched () возвращает NULL.

  3. Как только ETag в $_SERVER['HTTP_IF_NONE_MATCH'] совпадает с ETag моего документа, anyTagMatched () возвращает TRUE.

  4. Если ни один из Etag в $_SERVER['HTTP_IF_NONE_MATCH'] не соответствует моему документу ETag, anyTagMatched() возвращает FALSE.

  5. Если $_SERVER['HTTP_IF_MODIFIED_SINCE'] установлен и совпадает с датой "последнего изменения" моего документа, isExpired() возвращает ЛОЖЬ, в противном случае - ИСТИНА.

  6. Как только anyTagMatched() возвращает TRUE, я выдаю 304. Если anyTagMatched () вернул NULL, а isExpired() вернул FALSE, я могу выдать 304. В любой другой ситуации я обслуживаю свою страницу как обычно (я также выдаю последнюю версию Last- Заголовки Modified и ETag).


person AlexV    schedule 18.01.2010    source источник
comment
Взгляните на: - stackoverflow.com/ questions / 2000715 / - stackoverflow.com/questions/1583740/   -  person mr-sk    schedule 18.01.2010
comment
Согласно определению, значение без кавычек недопустимо (см. w3.org /Protocols/rfc2616/rfc2616-sec3.html#sec3.11).   -  person Gumbo    schedule 26.01.2010
comment
Приятно знать, я должен научиться читать эти определения полей в RFC! Пункт 1-C все еще недействителен, верно?   -  person AlexV    schedule 26.01.2010


Ответы (1)


Это нужно поставить в конец (переместить для лучшего обзора).

$anyTagMatched = anyTagMatched() ;
if( $anyTagMatched || ( ( null === $anyTagMatched ) && !isExpired() ) ) {
    notModified() ;
}
// Output content

Псевдокод (необходим обзор):

<?php

/**
 * Calculates eTag for the current resource.
 */
function calculateTag() {
}

/**
 * Gets date of the most recent change.
 */
function lastChanged() {
}

/**
 * TRUE if any tag matched
 * FALSE if none matched
 * NULL if header is not specified
 */
function anyTagMatched() {
    $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
        stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : 
        false ;

    if( false !== $if_none_match ) {
        $tags = split( ", ", $if_none_match ) ;
        $myTag = calculateTag() ;
        foreach( $tags as $tag ) {
            if( $tag == $myTag ) return true ;
        }
        return false ;
    }
    return null ;
}

function isExpired() {
    $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
        stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
        false;

    if( false !== $if_modified_since ) {
        // Compare time here; pseudocode.
        return ( $if_modified_since < lastChanged() ) ;
    }

    return true ;
}

function notModified() {
    header('HTTP/1.0 304 Not Modified');
    exit ;
}

Основной ответ здесь < / а>.

person St.Woland    schedule 18.01.2010