Проверяет ли Браузер условные заголовки внутри PUSH_PROMISE-фреймов?

Я знаю, что браузеры могут отправлять RST_STREAM-frames для отмены serverpush.

Имеет ли смысл отправлять заголовки Last-Modified или Etag внутри PUSH_PROMISE? Или проверка to-be-pushed ресурсов основана только на их URI (как Симона Борде ответила на следующий вопрос два года назад)?

Отменяет ли браузер отправку сервера, когда ресурс находится в кеше?

Точного ответа на этот вопрос я не нашел.


person Bodo Wissemann    schedule 30.12.2017    source источник


Ответы (2)


Когда сервер HTTP/2 отправляет ресурс, он генерирует фрейм PUSH_PROMISE для отправки клиенту и в то же время создает искусственный запрос, который обрабатывается так, как если бы его отправил удаленный клиент.

Помните, что кадр PUSH_PROMISE представляет собой запрос, который клиент сделает для этого ресурса, а не ответ.

Обычно содержимое заголовков кадра PUSH_PROMISE и заголовков синтетического запроса одинаково, но — в зависимости от реализации — это может быть не так.

Заголовки Last-Modified или ETag имеют смысл только в ответах, поэтому не имеет смысла добавлять их во фрейм PUSH_PROMISE.

Имеет ли смысл добавлять другие заголовки request, такие как If-Modified-Since, к PUSH_PROMISE, зависит от того, используются ли те же заголовки для искусственного запроса. Если используются одни и те же заголовки, как это обычно бывает, то добавление таких заголовков, как If-Modified-Since, влияет только на обработку на стороне сервера: сервер может сгенерировать 304 Not Modified при обработке синтетического запроса.

Однако серверу было бы странно отправлять PUSH_PROMISE для ресурса, за которым следует 304. Если сервер знает, что у клиента уже есть кешированный ресурс, он может также пропустить отправку PUSH_PROMISE.

Добавление заголовков response, таких как Last-Modified, к кадру PUSH_PROMISE не имеет смысла, поскольку PUSH_PROMISE представляет собой запрос.

Добавление условных заголовков request, таких как If-Modified-Since, обычно требует, чтобы сервер имел некоторые сведения о том, какие ресурсы ранее были предоставлены клиенту: он должен знать, был ли уже предоставлен ресурс, чтобы отправить 304 на сервер. client для отправленного ресурса заставит клиента использовать ресурс, уже присутствующий в его кеше.

person sbordet    schedule 30.12.2017
comment
Итак, внутри PUSH_PROMISE (кроме URI файла) нет ничего, что могло бы помочь браузеру решить, хочет ли он принять или отменить отправку? - person Bodo Wissemann; 01.01.2018

После более глубокого поиска я думаю, что нашел ответ:

pushBuilder's Апи говорит .lastModified():

Установите дату последнего изменения, которая будет использоваться для условных push-уведомлений.

и для .etag():

Установите etag, который будет использоваться для условных push-уведомлений.

Я неправильно понял эти объяснения и подумал, что указанные значения отправляются браузеру внутри PUSH_PROMISE, чтобы помочь ему решить, принять ли отправленный файл или отменить поток (путем отправки RST_STREAM).

На самом деле, кажется, что эти значения сообщают серверу, нужно ли ему отправлять что-либо. или не. Установив last-modified-date файла как .lastModified(), я получил поведение, описанное Симоне Борде в его комментарии выше: было отправлено 304, даже если файл не существовал в моем кеше.

Так что теперь совершенно ясно, что нет смысла устанавливать эти значения, не зная точно, что находится внутри кеша клиента.

Что-то вроде условных заголовков внутри PUSH_PROMISE, кажется, не существует прямо сейчас: я ничего не нашел об этом в спецификациях HTTP2, и, читая в хромовом трекере, я обнаружил, что Том Берган комментирует это при открытии (02.01.2017) проблема (https://bugs.chromium.org/p/chromium/issues/detail?id=232040#c62):

... Я думаю, что лучший способ справиться с этим случаем - преобразовать отправленный ответ в 304, когда отправленный ответ соответствует кэшированному ресурсу. Возможны две реализации:

  1. Не отменяйте отправку, пока не получите отправленные заголовки ответа (поскольку заголовки ответа содержат ETag и/или Last-Modified). Если отправленный ресурс уже кэширован, браузер преобразует отправленный ответ в 304 и отменит отправку. Однако, ИМО, это слишком долго ждет, чтобы отменить толчок.

  2. Добавьте условные заголовки, такие как If-Match, в PUSH_PROMISE, чтобы браузер точно знал, какой ресурс передается. Это хорошая идея, но она должна быть определена, прежде чем мы сможем ее реализовать. https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0522.html ...

Итак, то, что я ожидал (помочь браузеру проверить достоверность кэшированного ресурса, прочитав некоторую информацию заголовка, отправленную в PUSH_PROMISE), сейчас невозможно, но в конечном итоге будет. Кроме того, кажется, что cache-digest будет реализовано в браузерах где-то в будущем, что будет еще эффективнее, так как можно будет избежать ненужных пушей на сервере. Chrome уже работает над этим, как видно здесь: https://docs.google.com/document/d/1HhmyzKUPuWcCs8wG_GLSu3mvptygXtO2mBl5xlmEB-4/edit#

Пожалуйста, поправьте меня, если я сказал что-то не так.

person Bodo Wissemann    schedule 02.01.2018