В чем разница между "всегда" и "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
приписывать.