4. HTTP Message (Message HTTP)
4.1 Message Types (Types de Messages)
Les messages HTTP consistent en des requêtes (request) du client vers le serveur et des réponses (response) du serveur vers le client.
HTTP-message = Request | Response ; HTTP/1.1 messages
Les messages de requête (section 5) et de réponse (section 6) utilisent le format de message générique de RFC 822 [9] pour transférer des entités (entity) (la charge utile du message). Les deux types de messages se composent d'une ligne de départ (start line), de zéro ou plusieurs champs d'en-tête (header field) (également appelés "headers"), d'une ligne vide indiquant la fin des champs d'en-tête (c'est-à-dire une ligne sans rien avant le CRLF), et éventuellement d'un corps de message (message body).
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
Pour la robustesse, les serveurs devraient (SHOULD) ignorer toute ligne vide reçue à l'endroit où une Request-Line est attendue. En d'autres termes, si le serveur lit le flux de protocole au début d'un message et reçoit d'abord un CRLF, il devrait ignorer ce CRLF.
Certaines implémentations de clients HTTP/1.0 défectueuses génèrent des CRLF supplémentaires après les requêtes POST. Pour réitérer ce que le BNF interdit explicitement, les clients HTTP/1.1 ne doivent pas (MUST NOT) ajouter de CRLF supplémentaires avant ou après les requêtes.
4.2 Message Headers (En-têtes de Messages)
Les champs d'en-tête HTTP, y compris les champs d'en-tête général (general-header) (section 4.5), d'en-tête de requête (request-header) (section 5.3), d'en-tête de réponse (response-header) (section 6.2) et d'en-tête d'entité (entity-header) (section 7.1), suivent le même format générique que celui donné dans la section 3.1 de RFC 822 [9]. Chaque champ d'en-tête se compose d'un nom suivi d'un deux-points (":") et de la valeur du champ. Les noms de champs sont insensibles à la casse. La valeur du champ peut (MAY) être précédée d'un nombre quelconque de LWS, bien qu'un seul SP soit préféré. Les champs d'en-tête peuvent s'étendre sur plusieurs lignes en précédant chaque ligne supplémentaire d'au moins un SP ou HT. Les applications devraient (ought to) suivre la "forme commune" (common form) lors de la génération de constructions HTTP, si elle est connue ou indiquée, car il peut exister des implémentations qui ne peuvent accepter rien au-delà de la forme commune.
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>
Le field-content n'inclut aucun LWS de tête ou de queue : l'espace blanc linéaire apparaissant avant le premier caractère non blanc de field-value ou après le dernier caractère non blanc de field-value. Un tel LWS de tête ou de queue peut (MAY) être supprimé sans changer la sémantique de la valeur du champ. Tout LWS apparaissant entre les field-content peut (MAY) être remplacé par un seul SP avant d'interpréter la valeur du champ ou de transférer le message en aval.
L'ordre de réception des champs d'en-tête avec des noms de champs différents n'est pas important. Cependant, c'est une "bonne pratique" (good practice) d'envoyer d'abord les champs d'en-tête généraux, puis les champs d'en-tête de requête ou de réponse, et enfin les champs d'en-tête d'entité.
Plusieurs champs message-header avec le même field-name peuvent (MAY) être présents dans un message si et seulement si toute la field-value pour ce champ d'en-tête est définie comme une liste séparée par des virgules [c'est-à-dire #(values)]. Il doit (MUST) être possible de combiner les multiples champs d'en-tête en une seule paire "field-name: field-value", sans changer la sémantique du message, en ajoutant chaque field-value suivante à la première, chacune séparée par une virgule. L'ordre dans lequel les champs d'en-tête avec le même field-name sont reçus est donc important pour l'interprétation de la valeur de champ combinée, et par conséquent, un proxy ne doit pas (MUST NOT) changer l'ordre de ces valeurs de champ lors du transfert d'un message.
4.3 Message Body (Corps de Message)
Le message-body d'un message HTTP, s'il est présent, est utilisé pour transporter l'entity-body associé à la requête ou à la réponse. Le message-body diffère de l'entity-body uniquement lorsqu'un encodage de transfert (transfer-coding) a été appliqué, comme indiqué par le champ d'en-tête Transfer-Encoding (section 14.41).
message-body = entity-body
| <entity-body encoded as per Transfer-Encoding>
Transfer-Encoding doit (MUST) être utilisé pour indiquer tout encodage de transfert appliqué par une application pour assurer un transfert sûr et approprié du message. Transfer-Encoding est une propriété du message, plutôt que de l'entité, et peut donc (MAY) être ajouté ou supprimé par toute application intermédiaire.
Lorsqu'un message-body est présent dans un message, la longueur de transfert (transfer-length) de ce message-body est déterminée par les règles définies dans la section 4.4.
4.4 Message Length (Longueur du Message)
La longueur de transfert d'un message est la longueur du message-body tel qu'il apparaît dans le transfert. Lorsqu'un message-body est présent dans un message, la longueur de transfert de ce corps est déterminée par l'un des éléments suivants (par ordre de priorité) :
-
Tout message de réponse qui ne doit pas (MUST NOT) inclure un message-body (comme les réponses 1xx, 204 et 304 et toute réponse à une requête HEAD) est toujours terminé par la première ligne vide après les champs d'en-tête, quels que soient les champs d'en-tête d'entité présents dans le message.
-
Si un champ d'en-tête Transfer-Encoding est présent et n'est pas "identity", alors la longueur de transfert est définie par l'encodage de transfert "chunked", sauf si le message est terminé par la fermeture de la connexion.
-
Si un champ d'en-tête Content-Length (section 14.13) est présent, sa valeur décimale en octets représente à la fois l'Entity-Length et la transfer-length. Si ces deux longueurs sont différentes (c'est-à-dire si un champ d'en-tête Transfer-Encoding est présent), le champ d'en-tête Content-Length ne doit pas (MUST NOT) être envoyé. (Note : Certaines implémentations plus anciennes envoyaient incorrectement Content-Length avec un Transfer-Encoding non-identity.)
-
Si le message utilise le type de média "multipart/byteranges", et que la transfer-length n'est pas autrement spécifiée, alors ce type de média auto-délimitant (self-delimiting) définit la transfer-length. Ce type de média ne doit pas (MUST NOT) être utilisé sauf si l'expéditeur sait que le destinataire peut l'analyser ; la présence d'un champ d'en-tête Range chez un destinataire indique que le client peut analyser les réponses multipart/byteranges.
Un champ d'en-tête Range pourrait être transféré par un proxy HTTP/1.0 qui ne comprend pas multipart/byteranges ; dans ce cas, le serveur doit (MUST) délimiter le message avec un champ Content-Range.
-
Par la fermeture de la connexion par le serveur. (La fermeture de la connexion ne peut pas être utilisée pour indiquer la fin d'un corps de requête, car cela laisserait le serveur incapable de renvoyer une réponse.)
Pour la compatibilité avec les applications HTTP/1.0, les requêtes HTTP/1.1 contenant un message-body doivent (MUST) inclure un champ d'en-tête Content-Length valide sauf si on sait que le serveur est conforme à HTTP/1.1. Si une requête contient un message-body et n'inclut pas de Content-Length, le serveur devrait (SHOULD) répondre avec 400 (bad request) s'il ne peut pas déterminer la longueur du message, ou avec 411 (length required) s'il souhaite insister sur la réception d'un Content-Length valide.
Toutes les applications HTTP/1.1 doivent (MUST) accepter le transfer-coding "chunked" dans les messages de requête, même si l'application elle-même n'envoie pas de messages chunkés. Si une requête HTTP/1.1 inclut un message-body mais n'inclut pas de Content-Length, le serveur devrait (SHOULD) répondre avec 400 (bad request) s'il ne peut pas déterminer la longueur de la requête, ou avec 411 (length required) s'il souhaite insister sur la réception d'un Content-Length valide.
Si une requête contient un message-body et qu'aucun Content-Length n'est donné, le serveur devrait (SHOULD) répondre avec 400 (bad request) s'il ne peut pas déterminer la longueur du message, ou avec 411 (length required) s'il souhaite insister sur la réception d'un Content-Length valide.
Un message ne devrait pas (SHOULD NOT) inclure à la fois un champ d'en-tête Transfer-Encoding et un champ d'en-tête Content-Length. Si un message inclut les deux, Transfer-Encoding doit (MUST) supprimer Content-Length.
Lorsqu'une entité encodée par contenu est reçue et analysée, si l'encodage de contenu est connu, la longueur du message-body est déterminée par les données décodées.
4.5 General Header Fields (Champs d'En-tête Généraux)
Il existe certains champs d'en-tête qui ont une applicabilité générale pour les messages de requête et de réponse, mais qui ne s'appliquent pas à l'entité transférée. Ces champs d'en-tête s'appliquent uniquement au message en cours de transfert.
general-header = Cache-Control ; Section 14.9
| Connection ; Section 14.10
| Date ; Section 14.18
| Pragma ; Section 14.32
| Trailer ; Section 14.40
| Transfer-Encoding ; Section 14.41
| Upgrade ; Section 14.42
| Via ; Section 14.45
| Warning ; Section 14.46
Les noms de champs d'en-tête généraux ne peuvent être étendus de manière fiable qu'en changeant la version du protocole. Cependant, de nouveaux champs d'en-tête ou expérimentaux peuvent être attribués aux valeurs de champ sans changer la version du protocole. La section 7.1 définit la sémantique des champs d'en-tête d'entité.
Les champs d'en-tête non reconnus devraient (SHOULD) être traités comme des champs d'en-tête d'entité par le destinataire.