Benutzerdefinierte HTTP-Header: Namenskonventionen

1114

Einige unserer Benutzer haben uns gebeten, Daten zu ihrem Konto in die HTTP-Header von Anfragen aufzunehmen, die wir ihnen senden, oder sogar Antworten, die sie von unserer API erhalten. Was ist die allgemeine Konvention zum Hinzufügen von benutzerdefinierten HTTP-Headern in Bezug auf Benennung , Format ... usw.

Sie können auch jede intelligente Verwendung dieser Informationen, auf die Sie gestoßen sind, im Internet veröffentlichen. Wir versuchen dies zu implementieren, indem wir das Beste als Ziel verwenden :)

Julien Genestoux
quelle
25
Beachten Sie, dass Firewalls Antwortheaderfelder entfernen können. Einige entfernen alles, was in RFC 2616 (Juni 1999, HTTP 1.1) nicht erwähnt wird. Die Client-Seite sollte weiterhin ohne die neuen Felder verwendbar sein.
stesch
5
Beachten Sie, dass der Kommentar von @stesch bei Verwendung von HTTP S nicht gilt .
Code_dredd
1
Beachten Sie, dass der Kommentar von @code_dredd eine urbane Legende ist. Firewalls können HTTPS-Inhalte filtern. Siehe howtoforge.com/filtering-https-traffic-with-squid und watchguard.com/help/docs/wsm/xtm_11/en-us/content/en-us/…
stesch
@stesch Da Ihr Artikel den Proxy im Grunde genommen in etwas Ähnliches wie ein MiTM verwandelt (es wird eine verschlüsselte Client-Verbindung verwendet und dann eine neue hergestellt), können Sie fast alles tun, aber diese Tatsache negiert die Verschlüsselung aus dem PoV des Proxys b / c Es entschlüsselt den Inhalt des Clients selbst. In diesem Fall ist es aus der PoV des Proxys im Grunde so, als ob Sie HTTPS nicht an
erster

Antworten:

1171

Die Empfehlung ist war ihr Name mit „X“ zu starten. ZB X-Forwarded-For, X-Requested-With. Dies wird auch in Abschnitt 5 von RFC 2047 erwähnt .


Update 1 : Im Juni 2011 wurde der erste IETF-Entwurf veröffentlicht, um die Empfehlung zur Verwendung des Präfixes "X-" für nicht standardmäßige Header zu verwerfen . Der Grund dafür ist, dass, wenn nicht standardmäßige Header mit dem Präfix "X-" zum Standard werden, das Entfernen des Präfixes "X-" die Abwärtskompatibilität unterbricht und Anwendungsprotokolle dazu zwingen, beide Namen zu unterstützen (z. B. x-gzip& gzipsind jetzt gleichwertig). Die offizielle Empfehlung lautet also, sie nur sinnvoll ohne das Präfix "X-" zu benennen .


Update 2 : Im Juni 2012 wurde die Ablehnung der Empfehlung zur Verwendung des Präfixes "X-" als RFC 6648 offiziell . Nachfolgend finden Sie relevante Zitate:

3. Empfehlungen für Ersteller neuer Parameter

...

  1. SOLLTEN ihren Parameternamen NICHT "X-" oder ähnliche Konstrukte voranstellen.

4. Empfehlungen für Protokolldesigner

...

  1. Die Registrierung von Parametern mit dem Präfix "X-" oder ähnlichen Konstrukten sollte NICHT untersagt werden.

  2. Darf NICHT festgelegt werden, dass ein Parameter mit einem "X-" Präfix oder ähnlichen Konstrukten als nicht standardisiert zu verstehen ist.

  3. DARF NICHT festlegen, dass ein Parameter ohne "X-" Präfix oder ähnliche Konstrukte als standardisiert zu verstehen ist.

Beachten Sie, dass "SOLLTE NICHT" ("entmutigt") nicht mit "MUSS NICHT" ("verboten") identisch ist. Weitere Informationen zu diesen Schlüsselwörtern finden Sie in RFC 2119 . Mit anderen Worten, Sie können weiterhin Header mit dem Präfix "X-" verwenden, dies wird jedoch nicht mehr offiziell empfohlen und Sie können sie definitiv nicht so dokumentieren, als ob sie dem öffentlichen Standard entsprechen.


Zusammenfassung :

  • Die offizielle Empfehlung lautet, sie nur ohne das Präfix "X-" sinnvoll zu benennen
  • Sie können weiterhin Header mit dem Präfix "X-" verwenden, dies wird jedoch nicht mehr offiziell empfohlen, und Sie können sie definitiv nicht so dokumentieren, als ob sie dem öffentlichen Standard entsprechen
BalusC
quelle
306
So wie es viele Kinder gibt, die niemals als Profisportler enden werden, werden viele benutzerdefinierte Header niemals als Standards enden. Ich bin geneigt, das "X-" auf diesen zu behalten.
G-Mac
19
@ G-Mac Einverstanden. Es gibt so viele benutzerdefinierte Header, die niemals standardisiert werden. Die wenigen, die dies tun, ist es einfach, Ihren Code von if (header == "x-gzip")bis zu bearbeiten if (header == "x-gzip" || header == "gzip"). Was Ihre Analogie betrifft, so ist eine andere: Es ist wie das militärische Sprichwort: "Oh, es ist mühsam, jemanden von privat zu allgemein zu ändern. Von nun an sind Sie alle Generäle. Jetzt müssen wir nicht mehr so ​​viel arbeiten."
Cole Johnson
24
@ColeJohnson Ich bin mir nicht sicher, ob diese Analogie funktioniert. Das Problem hierbei ist, dass es keinen zentralen Punkt gibt, an dem Sie den Namen ändern können. Jeder einzelne Codeausschnitt, der x-gzip erwartet, muss jetzt geändert werden, oder der alte Header muss zusätzlich zum neuen weiterhin verwendet werden. Es ist vorzuziehen, mit RFC 6648 zu gehen.
Vinod
4
@ Vinod ja. Es macht Sinn, aber es gibt so viele vorgeschlagene Standards, die niemals das Licht der Welt erblicken werden. Für Dateitypen sicher; Löschen Sie das X-Präfix. Ich bin dagegen, aber mach weiter. Lassen Sie die Header OTOH nicht fallen. Es macht es einfach zu sehen und zu sagen: "Oh, es ist nicht Standard; ich kann es ignorieren" vs "Es gibt diese nicht Standard- X-Header, und dann gibt es diesen, den ich nicht erkenne; kann ich ihn sicher ignorieren?"
Cole Johnson
21
Obwohl der Ton von Cweeklys Antwort unnötig defensiv ist, glaube ich, dass er Recht hat, und sein Punkt löst das in diesem Kommentarthread dargestellte Problem. Kurz gesagt, versuchen Sie nicht zu identifizieren, ob ein Header "graduiert" oder nicht. Stellen Sie stattdessen fest, ob es sich um einen privaten oder öffentlichen Header handelt (anwendungsspezifisch oder "generisch" / "global"). Verwenden Sie für private Header optional, X-um sicherzustellen, dass keine Konflikte mit öffentlichen Headern auftreten (dank RFC6648, das sich mit öffentlichen Headern befasst), und verwenden Sie außerdem definitiv ein beliebiges privates Präfix. Verwenden Sie für öffentliche Header X-unter keinen Umständen.
Der
535

Die Frage muss noch einmal gelesen werden. Die tatsächlich gestellte Frage ähnelt nicht den Herstellerpräfixen in CSS-Eigenschaften, bei denen Zukunftssicherheit und Überlegungen zur Lieferantenunterstützung und zu offiziellen Standards angemessen sind. Die tatsächlich gestellte Frage ähnelt eher der Auswahl von Parameternamen für URL-Abfragen. Niemand sollte sich darum kümmern, was sie sind. Aber die Namensabstände der benutzerdefinierten sind eine absolut gültige - und übliche und korrekte - Sache.

Begründung:
Es geht um Konventionen zwischen Entwicklern für benutzerdefinierte, anwendungsspezifische Header - " Daten, die für ihr Konto relevant sind " -, die nichts mit Anbietern, Standardisierungsgremien oder Protokollen zu tun haben, die von Dritten implementiert werden sollen, außer dem Entwickler In Frage kommt lediglich die Vermeidung von Headernamen, die möglicherweise von Servern, Proxys oder Clients anderweitig verwendet werden. Aus diesem Grund sind die angegebenen Beispiele "X-Gzip / Gzip" und "X-Forwarded-For / Forwarded-For" umstritten. Die gestellte Frage bezieht sich auf Konventionen im Kontext einer privaten API, ähnlich den Namenskonventionen für URL-Abfrageparameter. Es ist eine Frage der Präferenz und des Namensabstands; Bedenken, dass "X-ClientDataFoo" von einem Proxy oder Anbieter ohne das "X" unterstützt wird

Das Präfix "X-" hat nichts Besonderes oder Magisches, aber es hilft zu verdeutlichen, dass es sich um einen benutzerdefinierten Header handelt. Tatsächlich helfen RFC-6648 et al., Die Verwendung eines "X-" Präfixes zu unterstützen, da - da Anbieter von HTTP-Clients und -Servern das Präfix aufgeben - Ihre app-spezifischen, privaten APIs, persönlichen Daten - Der Passing-Mechanismus wird durch die geringe Anzahl offizieller reservierter Headernamen noch besser gegen Namensraumkollisionen isoliert. Meine persönliche Präferenz und Empfehlung ist es jedoch, einen Schritt weiter zu gehen und z. B. "X-ACME-ClientDataFoo" auszuführen (wenn Ihr Widget-Unternehmen "ACME" ist).

Meiner Meinung nach ist die IETF-Spezifikation nicht spezifisch genug, um die Frage des OP zu beantworten, da sie nicht zwischen völlig unterschiedlichen Anwendungsfällen unterscheidet: (A) Anbieter, die neue global anwendbare Funktionen wie "Forwarded-For" einerseits einführen, vs. (B) App-Entwickler, die app-spezifische Zeichenfolgen an / von Client und Server übergeben. Die Spezifikation befasst sich nur mit der ersteren (A). Die Frage ist hier, ob es Konventionen für (B) gibt. Es gibt. Dazu müssen die Parameter alphabetisch gruppiert und von den vielen standardrelevanten Überschriften des Typs (A) getrennt werden. Die Verwendung des Präfixes "X-" oder "X-ACME-" ist für (B) bequem und legitim und steht nicht in Konflikt mit (A). Je mehr Anbieter "X-" für (A) nicht mehr verwenden, desto klarer werden die (B).

Beispiel:
Google (die in den verschiedenen Normungsgremien ein wenig Gewicht haben) verwendet - ab heute 20141102 in dieser geringfügigen Änderung meiner Antwort - derzeit "X-Mod-Pagespeed", um die Version ihres Apache-Moduls anzugeben an der Transformation einer bestimmten Antwort beteiligt. Schlägt jemand wirklich vor, dass Google "Mod-Pagespeed" ohne "X-" verwenden und / oder die IETF bitten sollte, seine Verwendung zu segnen?

Zusammenfassung:
Wenn Sie in Ihrer App benutzerdefinierte HTTP-Header (als manchmal geeignete Alternative zu Cookies) verwenden, um Daten an / von Ihrem Server zu übertragen, und diese Header ausdrücklich nicht dazu bestimmt sind, jemals außerhalb Ihres Kontexts verwendet zu werden Anwendung, Namensabstand mit einem "X-" oder "X-FOO-" Präfix ist eine vernünftige und übliche Konvention.

zweiwöchentlich
quelle
52
Ich würde mich freuen, wenn Downvoter meines Kommentars erklären könnten, welchen Teil meiner Antwort sie als unangenehm empfinden. Mein Ruf ist mir nicht so wichtig, aber ich bin wirklich neugierig. Wo liegt die Meinungsverschiedenheit? Vielen Dank.
zweiwöchentlich
56
Ich stimme Ihrer Antwort voll und ganz zu und es ist die einzige Antwort hier, die die tatsächlich gestellte Frage beantwortet. Wir sprechen hier von benutzerdefinierten, anwendungsspezifischen Headern, die in den HTTP-Standards niemals standardisiert werden dürfen. Gibt es eine gemeinsame Konvention für diese, die Menschen tendenziell verwenden? (wie sie mit "_" vielleicht prefixing dh: ( "_ClientDataFoo")?
Marchy
14
Danke Marchy, ja, die akzeptierte Antwort geht nicht auf die gestellte Frage ein. Die IETF-Ablehnung des Präfixes "X-" für nicht standardmäßige (aber generische) Header ist für benutzerdefinierte app-spezifische Header, die niemals standardisiert werden, irrelevant. Um Ihre Frage zu beantworten, ist es meiner Meinung nach und Erfahrung (16 Jahre Webdev) die beste Konvention, die oben genannten "X-ACME-ClientData" zu verwenden. "X-" v semantischer Name, den Sie mögen. :)
zweiwöchentlich
5
@DarrelMiller ... daher die Empfehlung, X-ACMECO-WIDGET-FOO zu verwenden. Ich bestehe darauf, dass für die gestellte Frage des OP die Verwendung von X- durch RFC-6648 und dergleichen einfach nicht kontraindiziert ist. Wenn Sie ein Anbieter sind, der ein Framework, eine Bibliothek oder ein Modul für die Verwendung in Projekten anderer Leute bereitstellt, ist das eine andere Geschichte, und folgen Sie diesem RFC auf jeden Fall zu einem T. Aber es ist nur für einzelne einmalige Anwendungen, wo benutzerdefiniert, umstritten App-spezifische Namenskonventionen für Header sind praktisch vollständig private APIs. Wie würden sie mit den Namen "aller anderen" zusammenstoßen? Wem würden die gehören?
zweiwöchentlich
11
Ich habe ehrlich gesagt ein wenig Probleme, die RFC-Argumentation zu verstehen. Zugegeben, wenn der Parameter standardisiert ist, gibt es sowohl x- als auch Nicht-x-Versionen. Dies ist nur dann ein Problem, wenn das Verhalten der x- und Nicht-x-Versionen identisch ist. Ich bin hier gestolpert, weil ich meiner API einen "im Namen von" -Header hinzufügen möchte. Es könnte eines Tages öffentlich werden (da es ein üblicher Anwendungsfall ist). Wenn ich "On-Behalf-Of" verwendet habe und eines Tages als Standard-Header hinzugefügt wird, wie hoch ist die Wahrscheinlichkeit, dass meine Semantik mit der standardisierten identisch ist?
narr4jesus
62

Das Format für HTTP-Header ist in der HTTP-Spezifikation definiert. Ich werde über HTTP 1.1 sprechen, für das die Spezifikation RFC 2616 ist . In Abschnitt 4.2, 'Nachrichtenkopfzeilen', wird die allgemeine Struktur einer Kopfzeile definiert:

   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>

Diese Definition beruht auf zwei Hauptpfeilern, Token und TEXT. Beide sind in Abschnitt 2.2, „Grundregeln“ definiert. Token ist:

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

Auf CHAR, CTL und Separatoren ruhen:

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

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

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

TEXT ist:

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

Wobei LWS ein linearer weißer Raum ist, dessen Definition ich nicht reproduzieren werde, und OCTET ist:

   OCTET          = <any 8-bit sequence of data>

Der Definition ist ein Hinweis beigefügt:

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].

Also zwei Schlussfolgerungen. Erstens, es ist klar , dass der Header - Name aus einer Teilmenge von ASCII - Zeichen zusammengesetzt sein muss - alphanumerics, einige Satzzeichen, nicht viel anders. Zweitens enthält die Definition eines Header- Werts nichts , was ihn auf ASCII beschränkt oder 8-Bit-Zeichen ausschließt: Er besteht explizit aus Oktetten, wobei nur Steuerzeichen gesperrt sind (beachten Sie, dass CR und LF als Steuerelemente betrachtet werden). Darüber hinaus impliziert der Kommentar zur TEXT-Produktion, dass die Oktette als ISO-8859-1 zu interpretieren sind und dass es einen Codierungsmechanismus (der übrigens schrecklich ist) gibt, um Zeichen außerhalb dieser Codierung darzustellen.

Um insbesondere auf @BalusC zu reagieren, ist es ziemlich klar, dass die Header-Werte gemäß der Spezifikation in ISO-8859-1 enthalten sind. Ich habe High-8859-1-Zeichen (insbesondere einige Vokale mit Akzent, wie sie auf Französisch verwendet werden) in einem Header von Tomcat gesendet und sie von Firefox korrekt interpretieren lassen. In gewissem Maße funktioniert dies sowohl in der Praxis als auch in der Theorie (Obwohl dies ein Standort-Header war, der eine URL enthält, und diese Zeichen in URLs nicht legal sind, war dies tatsächlich illegal, aber unter einer anderen Regel!).

Trotzdem würde ich mich nicht darauf verlassen, dass ISO-8859-1 auf allen Servern, Proxys und Clients funktioniert, also würde ich mich aus Gründen der defensiven Programmierung an ASCII halten.

Tom Anderson
quelle
3
Die neuere HTTP-Spezifikation RFC7230 besagt: "Neu definierte Header-Felder sollten ihre Feldwerte auf US-ASCII-Oktette beschränken."
Robert Tupelo-Schneck
23

RFC6648 empfiehlt, dass Sie davon ausgehen, dass Ihr benutzerdefinierter Header "standardisiert, öffentlich, allgemein bereitgestellt oder für mehrere Implementierungen verwendbar sein kann". Daher wird empfohlen, ihm nicht "X-" oder ähnliche Konstrukte voranzustellen.

Es gibt jedoch eine Ausnahme, "wenn es äußerst unwahrscheinlich ist, dass [Ihr Header] jemals standardisiert wird". Für solche "implementierungsspezifischen und privat genutzten" Header ist laut RFC ein Namespace wie ein Herstellerpräfix gerechtfertigt.

Edward Brey
quelle
6
"RFC6648 empfiehlt, dass Sie davon ausgehen, dass Ihr benutzerdefinierter Header" standardisiert, öffentlich, allgemein bereitgestellt oder über mehrere Implementierungen hinweg verwendbar wird. "Ich denke, dies gibt einen Grund, ein X-Präfix zu verwenden, da es wahrscheinlicher ist, dass etwas ohne Präfix standardisiert wird.
Konrad
@Konrad Wenn Sie davon ausgehen , dass der ähnliche Header eines anderen (nicht Ihr Header) standardisiert wird, können Sie einen Konflikt mit vermeiden X-, aber dies ist eine andere Annahme als in erster Linie bei RFC6648. Die Ausnahme des RFC berücksichtigt potenzielle Konflikte zwischen einem zukünftigen Standardheader und einem Header eines anderen Anbieters, dessen Technologie durch Unternehmenszusammenschluss usw. in Ihre integriert werden kann. Aus diesem Grund erfordert die Ausnahme ein Lieferantenpräfix.
Edward Brey
17

Das Hinzufügen oder korrekter Hinzufügen zusätzlicher HTTP-Header ist ein großartiges Tool zum Debuggen von Code, wenn nichts anderes.

Wenn eine URL-Anfrage eine Weiterleitung oder ein Bild zurückgibt, gibt es keine HTML-Seite, auf die die Ergebnisse des Debug-Codes vorübergehend geschrieben werden können - zumindest keine, die in einem Browser sichtbar ist.

Ein Ansatz besteht darin, die Daten in eine lokale Protokolldatei zu schreiben und diese Datei später anzuzeigen. Eine andere Möglichkeit besteht darin, vorübergehend HTTP-Header hinzuzufügen, die die zu debuggenden Daten und Variablen widerspiegeln.

Ich füge regelmäßig zusätzliche HTTP-Header wie X-fubar-somevar: oder X-testing-someresult: hinzu, um Dinge zu testen - und habe viele Fehler gefunden, die sonst sehr schwer zu verfolgen gewesen wären.

g1smd
quelle
2
Warum sollte er diesen "Standard" verwenden? Die Header funktionieren genauso. Sogar mit dem Präfix "WHO_EVER_READS_THIS_IS_DUMB_" ...
Der unglaubliche
16

Die Registrierung des Header-Feldnamens ist in RFC3864 definiert , und bei "X-" gibt es nichts Besonderes.

Soweit ich das beurteilen kann, gibt es keine Richtlinien für private Header. im Zweifel vermeiden Sie sie. Oder schauen Sie sich das HTTP Extension Framework ( RFC 2774 ) an.

Es wäre interessant, mehr über den Anwendungsfall zu erfahren. Warum können die Informationen nicht zum Nachrichtentext hinzugefügt werden?

Julian Reschke
quelle
13
Der Hauptgrund, warum ich über einige benutzerdefinierte Header
nachdenke,