В чем разница между "всегда" и "onsuccess" в конфигурации заголовка Apache?

У меня есть сайт, где виртуальные хосты определены в /etc/apache2/sites-enabled/ с заголовком, установленным с always вариант как этот:

Header always set X-Frame-Options DENY

Если я теперь установить тот же заголовок с помощью .htaccess в корневой папке сайта, но без always затем заголовок возвращается дважды в ответе сервера.

Настройка в .htaccess (среди других):

Header set X-Frame-Options DENY

Ответ сервера:

HTTP/1.1 200 OK
Date: Mon, 02 May 2016 16:02:29 GMT
Server: Apache/2.4.10 (Debian)
X-Frame-Options: DENY
Cache-Control: no-cache, no-store, must-revalidate, private
Pragma: no-cache
X-XSS-Protection: 1
X-Content-Type-Options: nosniff
Last-Modified: Mon, 02 May 2016 15:03:42 GMT
Accept-Ranges: bytes
Content-Length: 0
X-Frame-Options: DENY
X-XSS-Protection: 1
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, must-revalidate, private
Pragma: no-cache
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

Документы Apache говорят, что без always опция значение по умолчанию onsuccess используется. Но они также говорят, что "... значение по умолчанию onsuccess не ограничивает действие ответами с кодом статуса 2xx..." ( http://httpd.apache.org/docs/current/en/mod/mod_headers.html).

Но если я не добавлю alwaysтогда на страницах ошибок, таких как 301 и 404, заголовок не будет установлен. С другой стороны, если я добавлю always тогда заголовки могут быть установлены дважды, если я использую значение по умолчанию (т.е. onsuccess) в .htaccess, Как утверждают документы: "повторение этой директивы с обоими условиями имеет смысл в некоторых сценариях, потому что всегда не является расширенным набором результатов по отношению к существующим заголовкам". Установка заголовков дважды не всегда допустима для ответа HTTP, см. /questions/27329167/dopustimyi-li-dublikatyi-zagolovkov-otveta-http/27329173#27329173. Поэтому я хочу избежать этого, естественно.

Мой вопрос сейчас: когда именно я должен использовать onsuccess (т.е. значение по умолчанию) и когда always? Я должен признать, что даже после прочтения документов Apache пару раз я не совсем понимаю это. Прагматично кажется, что всегда используя always приводит к правильному / ожидаемому поведению.

Я также не понимаю, почему Apache пишет заголовок дважды, если он установлен в always а также onsuccess, Это кажется мне неправильным, но для этого должна быть веская причина, так как я предполагаю, что разработчики Apache знают о HTTP гораздо больше, чем я;-)

1 ответ

Мы используем Adobe Experience Manager с модулем Dispatcher [caching] для нашего веб-сервера Apache. Adobe недавно изменила приведенный ниже код. По сути, я считаю, что вам может потребоваться использовать синтаксис expr=, чтобы убедиться, что значение еще не установлено. Это должно устранить дубликаты.

Вот справочный код от Adobe:

Исходная конфигурация: Header always append X-Frame-Options SAMEORIGIN

Новая конфигурация: Header merge X-Frame-Options SAMEORIGIN "expr=%{resp:X-Frame-Options}!='SAMEORIGIN'"

Когда я спросил, Adobe привела мне следующие причины. Спасибо, Adobe.

Объяснение: Использование "слияния" вместо "добавления" предотвращает добавление значения записи в заголовок более одного раза.

expr= выражение: Директива применяется тогда и только тогда, когда выражение истинно. Подробная информация о синтаксисе и оценке выражений задокументирована в документации ap_expr. "Expr" просматривает заголовки ответа с сервера (сервер приложений издателя), чтобы убедиться, что он не включает SAMEORIGIN. Это гарантирует, что SAMEORGIN не дублируется в заголовке ответа, отправляемом обратно клиенту запроса.

Это необходимо, потому что тестирование показало, что когда AEM включает этот заголовок, Apache будет дублировать значение SAMEORIGIN даже с опцией слияния. Apache может выполнять правильное слияние, когда он получает заголовок от самого себя, но поскольку первый заголовок был установлен AEM вне экземпляра Apache, он становится странным (и требует дополнительного выражения).

Также кажется, что они не используют "всегда" с синтаксисом merge+expr. Возможно, чтобы также обойти странность Apache.

PS... не забудьте заменить SAMEORIGIN на DENY в вашем случае.

Это только частичный ответ, так как он не охватывает onsuccess приписывать. Он основан на опыте использования Apache 2.4.7 под управлением Ubuntu 14 OS. Надеюсь, это поможет вам.

Чистый set параметр, без атрибутов, в Header директива перезаписывает любой always атрибут, заставляя аргумент Header set быть единственным доставленным. Если такая же директива появляется в каталоге, то есть в файле.htaccess на основе файловой системы, она имеет приоритет над той же директивой, отмеченной в файле определения виртуального хоста, связанном с этим каталогом. Если атрибут always отмечается дополнительно, что это приводит к тому, что любая, одинаковая или разная нотация одной и той же директивы добавляется к ответу сервера вместо его перезаписи / замены.

Вероятно, onsuccess атрибут, который я, к сожалению, не имею времени изучать сейчас, может обрабатываться так же, как always приписывать.

Другие вопросы по тегам