Спеціальні заголовки HTTP: іменування умов


1113

Кілька наших користувачів попросили нас включити дані щодо свого облікового запису в заголовки HTTP запитів, які ми надсилаємо їм, або навіть відповіді, які вони отримують від нашого API. Яка загальна умова додавати власні заголовки HTTP з точки зору найменування , форматування ... тощо.

Крім того, сміливо публікуйте будь-яке розумне використання цих, про які ви натрапили в Інтернеті; Ми намагаємось реалізувати це, використовуючи те, що найкраще в якості цілі :)


25
Майте на увазі, що міжмережеві стіни можуть видаляти поля заголовка відповідей. Деякі видаляють все, що не згадується в RFC 2616 (червень 1999, HTTP 1.1). Клієнтська сторона все-таки повинна бути корисною без нових полів.
stesch

5
Зверніть увагу , що коментар по @stesch не застосовується при використанні HTTP S .
code_dredd

1
Зауважте, що коментар @code_dredd - міська легенда. Брандмауери можуть фільтрувати вміст HTTPS. Дивіться howtoforge.com/filtering-https-traffic-with-squid і watchguard.com/help/docs/wsm/xtm_11/en-us/content/en-us/…
stesch

@stesch З огляду на те, що ваша стаття в основному перетворює проксі-сервер на щось подібне до MiTM (воно займає зашифроване підключення клієнта, а потім робить нове), тоді впевнено, ви можете зробити майже все, але цей факт заперечує шифрування з PoV b / проксі c - це розшифрування самого вмісту клієнта. У такому випадку з PoV проксі-сервера, як ніби ви не використовуєте HTTPS на 1-му місці ...
code_dredd

Відповіді:


1171

Ця рекомендація буде була почати своє ім'я з «Х-». Наприклад X-Forwarded-For, X-Requested-With. Про це також згадується в розділі 5 RFC 2047 .


Оновлення 1 : У червні 2011 року був опублікований перший проект IETF, щоб зняти рекомендації щодо використання префікса "X-" для нестандартних заголовків. Причина полягає в тому, що коли нестандартні заголовки з префіксом "X-" стають стандартними, вилучення префіксу "X-" порушує сумісність назад, змушуючи протоколи додатків підтримувати обидва імені (наприклад, x-gzip& gzipтепер є рівнозначними). Отже, офіційна рекомендація - просто назвати їх розумно, без префікса "X-".


Оновлення 2 : У червні 2012 року припинення рекомендації щодо використання префіксу "X-" стало офіційним як RFC 6648 . Нижче наведено релевантні цитати:

3. Рекомендації для творців нових параметрів

...

  1. НЕ БУДЕ ПРЕФІКСУвати свої назви параметрів "X-" або подібними конструкціями.

4. Рекомендації для конструкторів протоколів

...

  1. НЕ БУДЕ забороняти реєструвати параметри з префіксом "X-" або подібними конструкціями.

  2. НЕ МОЖЕ НЕ встановлювати, що параметр з префіксом "X-" або подібними конструкціями потрібно розуміти як нестандартний

  3. НЕ МОЖЕ НЕ встановлювати, що параметр без префікса "X-" або подібні конструкції потрібно розуміти як стандартизований.

Зауважте, що "ПОТРІБНО НЕ" ("відмовлятись") не те саме, що "ПОВИНЕН НЕ" ("заборонено"), див. Також RFC 2119 для іншої характеристики цих ключових слів. Іншими словами, ви можете продовжувати використовувати заголовки "X-", але це офіційно більше не рекомендується, і ви, безумовно, не можете їх документувати так, ніби вони є державним стандартом.


Підсумок :

  • офіційна рекомендація - просто назвати їх розумно, без префікса "X-"
  • ви можете продовжувати використовувати заголовки "X-", але це офіційно більше не рекомендується, і ви, безумовно, не можете їх документувати так, ніби вони є державним стандартом

306
Так само, як є багато дітей, які ніколи не стануть професійними спортсменами, так і багато нестандартних заголовків ніколи не стануть стандартами. Я схильний тримати "X-" на цих.
G-Mac

19
@ G-Mac Погодився. Є так багато призначених для користувача заголовків , які ніколи не будуть в кінцевому підсумку стандартизовані. Нечисленні, які це роблять, просто відредагувати свій код з if (header == "x-gzip")до if (header == "x-gzip" || header == "gzip"). Що стосується вашої аналогії, ось ще одна: це як військові, які говорять "О, важко змінити когось із рядового на генерала. Отже, відтепер ви всі генерали. Зараз нам не потрібно робити стільки роботи".
Коул Джонсон

24
@ColeJohnson Не впевнений, чи працює аналогія. Проблема тут полягає в тому, що немає центральної точки, яку можна змінити на ім'я. Кожен фрагмент коду, який очікує x-gzip, зараз має бути змінений, або старий заголовок потрібно продовжувати використовувати на додаток до нового. Краще їхати з RFC 6648.
vinod

4
@Vinod так. Це має сенс, але є так багато запропонованих стандартів, які ніколи не побачать світла дня. Для типів файлів обов'язково; скиньте X-префікс. Я проти, але вперед і роби це. Для заголовків OTOH не кидайте його. Це дозволяє легко дивитися і переходити: "О, це нестандартно; я можу проігнорувати це" проти "є ці нестандартні X-заголовки, а потім є цей, якого я не впізнаю; чи можу я ігнорувати його безпечно?"
Коул Джонсон

21
Хоча тон відповіді Cweekly є надмірно захисним, я вважаю, що він правильний, і його точка вирішує проблему, проілюстровану в цій темі коментарів. Коротше кажучи, не намагайтеся визначити, буде "заголовка" закінчуватися чи ні; натомість визначте, чи це приватний чи загальнодоступний заголовок (специфічний для програми чи "загальний" / "глобальний"). Для приватних заголовків необов’язково використовуйте, X-щоб не забезпечити зіткнення з загальнодоступними заголовками (завдяки RFC6648, який стосується загальнодоступних заголовків), а також напевно використовуйте довільний приватний префікс. Для загальнодоступних заголовків не використовуйте X-жодних обставин.
TNE

535

Питання підлягає перечитанню. Справжнє задане запитання не схоже на префікси постачальника у властивостях CSS, де доречна перевірка та роздуми щодо підтримки постачальника та офіційних стандартів є доцільним. Справжнє задане питання більше схоже на вибір імен параметрів URL-запиту. Ніхто не повинен байдуже, що вони є. Але інтервали між іменами на власні - цілком дійсна річ - і звичайна, і правильна.

Обґрунтування: мова
йде про домовленості серед розробників щодо користувацьких, спеціальних заголовків - " даних, що стосуються їх облікового запису ", - які не мають нічого спільного з постачальниками, органами зі стандартів або протоколами, що мають бути реалізовані третіми сторонами, за винятком розробника у питанні просто потрібно уникати імен заголовків, які можуть використовувати інші сервери, проксі або клієнти. З цієї причини наведені приклади "X-Gzip / Gzip" та "X-Forwarded-For / Forwarded-For" є спірними. Поставлене запитання стосується конвенцій у контексті приватного API, схожого на конвенції іменування параметрів запиту URL. Це питання переваги та інтервалу імен; стурбованість тим, що "X-ClientDataFoo" підтримується будь-яким проксі-сервером чи постачальником без "X"

У префіксі "X-" немає нічого особливого або магічного, але це допомагає зрозуміти, що це власний заголовок. Насправді, RFC-6648 та ін допомагають посилити справу щодо використання префікса "X-", оскільки - як постачальники клієнтів HTTP та сервери відмовляються від префікса - ваш додаток, приватний API, персональні дані, механізм пропускання стає ще краще захищеним від зіткнень простору імен з невеликою кількістю офіційних зарезервованих імен заголовків. Однак, мої особисті переваги та рекомендації - зробити крок далі і зробити, наприклад, "X-ACME-ClientDataFoo" (якщо ваша компанія-віджет - "ACME").

IMHO специфікація IETF недостатньо специфічна, щоб відповісти на питання ОП, оскільки не вдається розрізнити абсолютно різні випадки використання: (A) постачальники, що впроваджують нові глобально застосовні функції, такі як "Forwarded-For", з одного боку, проти (B) розробники додатків, що передають спеціальні рядки для клієнта та сервера. Спекуляція стосується лише колишнього, (A). Тут питання полягає в тому, чи існують конвенції для (B). Існує. Вони передбачають групування параметрів за алфавітом та відокремлення їх від багатьох заголовків типу A (відповідних стандартам). Використання префікса "X-" або "X-ACME-" є зручним і законним для (B) і не суперечить (A). Чим більше продавці перестануть використовувати "X-" для (A), тим чіткіше виразними стануть (B).

Приклад:
Google (які мають невелику вагу в різних органах зі стандартів) - станом на сьогодні 20141102 у цьому невеликому редагуванні моєї відповіді - наразі використовує "X-Mod-Pagespeed", щоб вказати версію свого модуля Apache бере участь у перетворенні заданої відповіді. Хтось дійсно пропонує, що Google повинен використовувати "Mod-Pagespeed" без "X-" та / або просити IETF благословити його використання?

Підсумок:
Якщо ви використовуєте власні заголовки HTTP (як іноді відповідну альтернативу файлам cookie) у вашій програмі для передачі даних на / з вашого сервера, і ці заголовки, явно, НЕ призначені ніколи використовуватись поза контекстом вашого додаток, розміщення їх іменами з префіксом "X-" або "X-FOO-" - це розумна і поширена умова.


52
Я був би вдячний, якби будь-які респонденти мого коментаря могли пояснити, яку частину моєї відповіді вони вважають заперечною. Мене так не хвилює моя оцінка репутації, але мені справді цікаво. Де криється незгода? Дякую.
cweekly

56
Я повністю згоден з вашою відповіддю, і це єдина відповідь, яка відповідає на фактично задане питання. Тут ми говоримо про власні, спеціальні заголовки, які ніколи не повинні бути стандартизовані у стандартах HTTP. Чи існує для них загальна умова, яку люди зазвичай використовують? (наприклад, префіксація їх "_" можливо? тобто: ("_ClientDataFoo")
березень

14
Дякую Марчі, так, прийнята відповідь не відповідає на поставлене запитання. Знеприйняття IETF префікса "X-" для нестандартних (але загальних) заголовків не має значення для спеціальних заголовків програм, які ніколи не будуть стандартизовані. Щоб відповісти на ваше запитання, на мою думку та досвід (16 років webdev), найкращим умовою є використання вищезгаданої "X-ACME-ClientData". "X-" bc це не стандартно (і ніколи не буде, через що депресія IETF тут суперечлива), "ACME-", щоб простір назв для вашої компанії "ACME" або конкретної програми, а "ClientData" може бути будь-якою семантичне ім'я, яке вам подобається. :)
cweekly

5
@DarrelMiller ... звідси рекомендується використовувати X-ACMECO-WIDGET-FOO. Я наполягаю на тому, що на запитання ОП, як було задано, використання X- просто не протипоказано RFC-6648 тощо. Якщо ви постачальник, який надає рамки, бібліотеку чи модуль для використання в проектах інших людей, це вже інша історія, і, безумовно, слідкуйте за цим RFC до T. Але це просто спір для окремих разових додатків, де користувацькі Конвенції про іменування заголовків для додатків фактично є повністю приватними API. Як би вони зіткнулися з іменами "всіх інших"? Чиї це були б?
cweekly

11
Я, чесно, маю невеликі проблеми з розумінням міркувань RFC. Зрозуміло, що якщо і коли параметр стандартизований, то будуть як x-, так і non-x- версії. Це лише проблема, якщо поведінка версій x- та non-x- однакова. Я натрапив сюди, бо дивлюсь на додавання заголовка "від імені" до мого API. Він може стати загальнодоступним через якийсь день (оскільки це звичайний вид використання). Якщо я використав "On-Behalf-Of" і коли-небудь вони додадуть, що як стандартний заголовок, які шанси на те, що моя семантика буде ідентичною стандартизованій?
crazy4jesus

62

Формат заголовків HTTP визначений у специфікації HTTP. Я буду говорити про HTTP 1.1, специфікацією якого є RFC 2616 . У розділі 4.2 «Заголовки повідомлень» визначена загальна структура заголовка:

   message-header = field-name ":" [ field-value ]
   field-name     = token
   field-value    = *( field-content | LWS )
   field-content  = <the OCTETs making up the field-value
                    and consisting of either *TEXT or combinations
                    of token, separators, and quoted-string>

Це визначення базується на двох основних стовпах, лексемі та TEXT. Обидва визначені в розділі 2.2 "Основні правила". Токен:

   token          = 1*<any CHAR except CTLs or separators>

У свою чергу, відпочиваючи на CHAR, CTL та сепараторах:

   CHAR           = <any US-ASCII character (octets 0 - 127)>

   CTL            = <any US-ASCII control character
                    (octets 0 - 31) and DEL (127)>

   separators     = "(" | ")" | "<" | ">" | "@"
                  | "," | ";" | ":" | "\" | <">
                  | "/" | "[" | "]" | "?" | "="
                  | "{" | "}" | SP | HT

ТЕКСТ:

   TEXT           = <any OCTET except CTLs,
                    but including LWS>

Де LWS - це лінійний білий простір, визначення якого я не відтворюватиму, а OCTET:

   OCTET          = <any 8-bit sequence of data>

Є примітка, що супроводжує визначення:

The TEXT rule is only used for descriptive field contents and values
that are not intended to be interpreted by the message parser. Words
of *TEXT MAY contain characters from character sets other than ISO-
8859-1 [22] only when encoded according to the rules of RFC 2047
[14].

Отже, два висновки. По-перше, зрозуміло, що заголовок ім'я повинно складатися з підмножини символів ASCII - буквено-цифрових знаків, деяких пунктуацій, не багато іншого. По-друге, у визначенні значення заголовка немає нічого, що обмежує його на ASCII або виключає 8-бітові символи: воно явно складається з октетів, лише заборонені символи управління (зауважте, що CR та LF вважаються елементами управління). Крім того, коментар до виробництва TEXT передбачає, що октети слід інтерпретувати як такі, що знаходяться в ISO-8859-1, і що існує механізм кодування (який, до речі, жахливо) для представлення символів поза цим кодуванням.

Отже, щоб реагувати на @BalusC, зокрема, цілком зрозуміло, що згідно зі специфікацією, значення заголовків знаходяться в ISO-8859-1. Я надсилав символи високого рівня 8859-1 (зокрема, деякі голосні наголошені, як це використовується французькою мовою), в заголовку з Tomcat, і їх інтерпретував Firefox правильно, так що певною мірою це працює як на практиці, так і в теорії (хоча це був заголовок Location, який містить URL-адресу, і ці символи не є законними в URL-адресах, тому це було фактично незаконно, але за іншим правилом!).

Втім, я не покладаюся на ISO-8859-1, що працює на всіх серверах, проксі-серверах та клієнтах, тому я б дотримувався ASCII як питання оборонного програмування.


3
Новіша специфікація HTTP RFC7230 говорить, що "Щойно визначені поля заголовка
Роберт Тупело-Шнек

23

RFC6648 рекомендує припустити, що ваш власний заголовок "може стати стандартизованим, загальнодоступним, широко розгорнутим або придатним для використання в декількох реалізаціях". Тому він рекомендує не префіксувати його "X-" або подібними конструкціями.

Однак є виняток, "коли вкрай малоймовірно, що [ваш заголовок] коли-небудь стандартизується". Для таких заголовків, що стосуються конкретної реалізації та приватного використання, RFC каже, що обґрунтований простір імен, такий як префікс постачальника.


6
"RFC6648 рекомендує припустити, що ваш власний заголовок" може стати стандартизованим, загальнодоступним, широко розгорнутим або придатним для використання в декількох реалізаціях ". Я думаю, що це дає підставу використовувати X-префікс, тому що швидше за все щось без будь-якого префікса може стати стандартизованим.
Konrad

@Konrad Якщо ви припускаєте, що чужий аналогічний заголовок (а не ваш заголовок) може стати стандартизованим, ви можете уникнути конфлікту X-, але це інше припущення, ніж головне, ніж RFC6648. Виняток RFC пояснює можливі конфлікти між майбутнім стандартним заголовком та заголовком іншого постачальника, технологія якого може бути інтегрована з вашим шляхом злиття компанії тощо. Тому виняток вимагає префікса постачальника.
Едвард Брей

17

Змінення або, правильніше, додавання додаткових заголовків HTTP - це чудовий інструмент налагодження коду, якщо нічого іншого.

Коли запит URL повертає переспрямування або зображення, немає HTML-сторінки "сторінки", щоб тимчасово записати результати налагоджувального коду до - принаймні, не такого, який видно у браузері.

Один із підходів - записати дані в локальний файл журналу та переглянути цей файл пізніше. Інша полягає у тимчасовому додаванні заголовків HTTP, що відображають дані та змінні, що піддаються налагодженню.

Я регулярно додаю додаткові заголовки HTTP, як-от X-fubar-somevar: або X-testing-someresult: щоб перевірити речі - і знайшов багато помилок, які інакше було б важко відстежити.


2
Чому він повинен використовувати цей «стандарт»? Заголовки працюють однаково. Навіть із префіксом "WHO_EVER_READS_THIS_IS_DUMB_" ...
Неймовірний

16

Реєстр імен поля заголовка визначений в RFC3864 , і немає нічого особливого з "X-".

Наскільки я можу сказати, для приватних заголовків немає вказівок; сумнівайтеся, уникайте їх. Або подивіться на HTTP Extension Framework ( RFC 2774 ).

Було б цікаво розібратися більше у випадку використання; чому інформація не може бути додана до тіла повідомлення?


13
Основна причина, яку я вважаю деякими користувацькими заголовками, - це те, що я можу приймати рішення про маршрутизацію, не
розбираючи
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.