2011-02-22 3 views
0

Я использую библиотеку кэширования, которая имеет функцию, показанную ниже. Он пытается захватить eTags из запроса на 5-й строке, но eTags никогда не устанавливаются.Понять Etags HTTP Header

Когда у ЗАПРОСА есть eTags? и как вы можете их установить?

Спасибо.

public function isNotModified(Request $request) 
{ 
    $lastModified = $request->headers->get('If-Modified-Since'); 

    $notModified = false; 
    if ($etags = $request->getEtags()) { 
     $notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified); 
    } elseif ($lastModified) { 
     $notModified = $lastModified == $this->headers->get('Last-Modified'); 
    } 

    if ($notModified) { 
     $this->setNotModified(); 
    } 

    return $notModified; 
} 
+0

[ETag] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19), если только поле заголовка ответа: «Поле заголовка ответа ETag предоставляет текущее значение тег объекта для запрошенного варианта. " – Gumbo

+0

Связанный: http://stackoverflow.com/questions/5081397/understand-if-modified-since-http-header И действительно,' ETag' появляется только в заголовке ответа. Контр-заголовок в запросах - 'If-None-Match', как было указано в вашем другом вопросе. – BalusC

ответ

2

ETag header field предназначен только для ответов:

поле заголовка отклика ETag обеспечивает текущее значение тега объекта для запрошенного варианта.

Но метод getEtags может быть тегами из If-None-Match header field:

Если какие-либо из тэгов объекта соответствует тегу объекта, который был бы возвращен в ответ на аналогичный запрос GET (без заголовка If-None-Match) на этом ресурсе или если задано «*», и любой существующий объект существует для этого ресурса, тогда сервер НЕ ДОЛЖЕН выполнять запрошенный метод, если это не требуется, потому что ресурс дата модификации не соответствует той, которая указана в If-Modi fied-Since заголовок поля в запросе. Вместо этого, если метод запроса был GET или HEAD, сервер СЛЕДУЕТ ответить с ответом 304 (Not Modified), включая поля заголовка, связанные с кешем (в частности, ETag) одного из сущностей, которые соответствуют. Для всех других методов запроса сервер ДОЛЖЕН отвечать статусом 412 (Precondition Failed).

Это, кажется, соответствует данный код в точности (я переставить первое предложение, чтобы соответствовать код):

// the server MUST NOT perform the requested method 
$notModified = (
    // if any of the entity tags match the entity tag of the entity that 
    // would have been returned in the response to a similar GET request 
    // (without the If-None-Match header) on that resource 
    in_array($this->getEtag(), $etags) 
    // or if "*" is given and any current entity exists for that resource 
    || in_array('*', $etags)) 
    // unless required to do so because the resource's modification 
    // date fails to match that supplied in an If-Modified-Since header 
    // field in the request. 
    && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified); 

Последнее выражение (!$lastModified || $this->headers->get('Last-Modified') == $lastModified) эквивалентно !($lastModified && $this->headers->get('Last-Modified') != $lastModified), который соответствует последней фразе часть лучше.

+0

проверяет заголовок if_none_match. Это намного сложнее, чем я думал. Я просто хочу СЧИТАТЬ! – Mike

+0

@Mike: Хорошо, спасибо. См. Мое обновление. – Gumbo

+0

@Mike: если все, что вы хотите, заставляет браузер кэшировать ресурс, просто добавьте заголовки 'ETag',' Last-Modified' и 'Expires' в ** ответ ** ресурса. Затем, когда последующий запрос приходит с 'If-Modified-Since' или' If-None-Match', просто проверяйте их и обрабатывайте соответственно, возвращая 304 или измененный ресурс, о котором идет речь. – BalusC