2. Architecture
HTTP a été créé pour l'architecture du World Wide Web (WWW) et a évolué au fil du temps afin de répondre aux besoins de passage à l'échelle d'un système hypertexte mondial. Une grande partie de cette architecture se reflète dans la terminologie et les productions syntaxiques utilisées pour définir HTTP.
2.1. Messagerie client/serveur
HTTP est un protocole requête/réponse sans état qui fonctionne en échangeant des messages (Section 3) sur une « connexion » fiable de couche transport ou de couche session (Section 6). Un « client » HTTP est un programme qui établit une connexion à un serveur dans le but d'envoyer une ou plusieurs requêtes HTTP. Un « serveur » HTTP est un programme qui accepte des connexions afin de traiter des requêtes HTTP en envoyant des réponses HTTP.
Les termes « client » et « serveur » ne désignent que les rôles que ces programmes jouent pour une connexion donnée. Un même programme peut agir comme client sur certaines connexions et comme serveur sur d'autres. Le terme « agent utilisateur » désigne l'un quelconque des divers programmes clients qui initient une requête, notamment (mais sans s'y limiter) les navigateurs, les araignées (robots fondés sur le Web), les outils en ligne de commande, les applications personnalisées et les applications mobiles. Le terme « serveur d'origine » désigne le programme qui peut produire à l'origine les réponses faisant autorité pour une ressource cible donnée. Les termes « expéditeur » et « destinataire » désignent respectivement toute implémentation qui envoie ou qui reçoit un message donné.
HTTP s'appuie sur la norme relative aux identifiants de ressource uniformes (Uniform Resource Identifier, URI) [RFC3986] pour indiquer la ressource cible (Section 5.1) et les relations entre les ressources. Les messages sont transmis dans un format similaire à celui utilisé par le courrier Internet [RFC5322] et par les Multipurpose Internet Mail Extensions (MIME) [RFC2045] (voir Appendix A de [RFC7231] pour les différences entre les messages HTTP et MIME).
La plupart des communications HTTP consistent en une requête de récupération (GET) d'une représentation d'une ressource identifiée par un URI. Dans le cas le plus simple, cela peut se faire au moyen d'une seule connexion bidirectionnelle (===) entre l'agent utilisateur (UA) et le serveur d'origine (O).
request >
UA ======================================= O
< response
Un client envoie une requête HTTP à un serveur sous la forme d'un message de requête, commençant par une ligne de requête qui comprend une méthode, un URI et une version de protocole (Section 3.1.1), suivie de champs d'en-tête contenant des modificateurs de requête, des informations sur le client et des métadonnées de représentation (Section 3.2), d'une ligne vide indiquant la fin de la section d'en-tête, et enfin d'un corps de message contenant le corps de charge utile (le cas échéant, Section 3.3).
Un serveur répond à la requête d'un client en envoyant un ou plusieurs messages de réponse HTTP, chacun commençant par une ligne d'état qui comprend la version de protocole, un code de succès ou d'erreur et une phrase de raison textuelle (Section 3.1.2), éventuellement suivie de champs d'en-tête contenant des informations sur le serveur, des métadonnées de ressource et des métadonnées de représentation (Section 3.2), d'une ligne vide indiquant la fin de la section d'en-tête, et enfin d'un corps de message contenant le corps de charge utile (le cas échéant, Section 3.3).
Une connexion peut être utilisée pour plusieurs échanges requête/réponse, comme défini à la Section 6.3.
L'exemple suivant illustre un échange de messages typique pour une requête GET (Section 4.3.1 de [RFC7231]) sur l'URI « http://www.example.com/hello.txt » :
Requête du client :
GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi
Réponse du serveur :
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
Hello World! My payload includes a trailing CRLF.
2.2. Diversité des implémentations
Lorsqu'on réfléchit à la conception de HTTP, il est facile de tomber dans le piège consistant à penser que tous les agents utilisateurs sont des navigateurs généralistes et que tous les serveurs d'origine sont de grands sites Web publics. Ce n'est pas le cas en pratique. Parmi les agents utilisateurs HTTP courants figurent les appareils électroménagers, les chaînes hi-fi, les balances, les scripts de mise à jour de micrologiciels, les programmes en ligne de commande, les applications mobiles et des dispositifs de communication de toutes formes et de toutes tailles. De même, parmi les serveurs d'origine HTTP courants figurent les unités domotiques, les composants réseau configurables, les machines de bureau, les robots autonomes, les fils d'actualité, les caméras de circulation, les sélecteurs de publicité et les plateformes de diffusion vidéo.
Le terme « agent utilisateur » n'implique pas qu'un utilisateur humain interagit directement avec l'agent logiciel au moment de la requête. Dans de nombreux cas, un agent utilisateur est installé ou configuré pour s'exécuter en arrière-plan et conserver ses résultats en vue d'un examen ultérieur (ou ne conserver qu'un sous-ensemble de ces résultats, ceux qui pourraient être intéressants ou erronés). Les araignées, par exemple, reçoivent typiquement un URI de départ et sont configurées pour adopter un certain comportement lorsqu'elles parcourent le Web comme un graphe hypertexte.
La diversité des implémentations de HTTP signifie que tous les agents utilisateurs ne peuvent pas faire de suggestions interactives à leur utilisateur ni fournir un avertissement adéquat en matière de sécurité ou de vie privée. Dans les rares cas où cette spécification impose de signaler des erreurs à l'utilisateur, il est acceptable que ce signalement ne soit observable que dans une console d'erreurs ou un fichier journal. De même, les exigences selon lesquelles une action automatisée doit être confirmée par l'utilisateur avant de se poursuivre peuvent être satisfaites au moyen de choix de configuration anticipés, d'options d'exécution, ou simplement en évitant l'action non sûre ; une confirmation n'implique aucune interface utilisateur particulière ni aucune interruption du traitement normal si l'utilisateur a déjà fait ce choix.
2.3. Intermédiaires
HTTP permet d'utiliser des intermédiaires pour satisfaire des requêtes à travers une chaîne de connexions. Il existe trois formes courantes d'intermédiaire HTTP : le proxy, la passerelle et le tunnel. Dans certains cas, un même intermédiaire peut agir comme serveur d'origine, proxy, passerelle ou tunnel, en changeant de comportement selon la nature de chaque requête.
> > > >
UA =========== A =========== B =========== C =========== O
< < < <
La figure ci-dessus montre trois intermédiaires (A, B et C) entre l'agent utilisateur et le serveur d'origine. Un message de requête ou de réponse qui parcourt toute la chaîne traverse quatre connexions distinctes. Certaines options de communication HTTP peuvent ne s'appliquer qu'à la connexion avec le voisin le plus proche non-tunnel, qu'aux extrémités de la chaîne, ou à toutes les connexions le long de la chaîne. Bien que le schéma soit linéaire, chaque participant peut être engagé dans plusieurs communications simultanées. Par exemple, B peut recevoir des requêtes de nombreux clients autres que A, et/ou transmettre des requêtes à des serveurs autres que C, au moment même où il traite la requête de A. De même, des requêtes ultérieures peuvent être envoyées par un chemin de connexions différent, souvent en fonction d'une configuration dynamique d'équilibrage de charge.
Les termes « amont » (upstream) et « aval » (downstream) sont utilisés pour décrire les exigences directionnelles par rapport au flux de messages : tous les messages circulent de l'amont vers l'aval. Les termes « entrant » (inbound) et « sortant » (outbound) sont utilisés pour décrire les exigences directionnelles par rapport au chemin de la requête : « entrant » signifie vers le serveur d'origine et « sortant » signifie vers l'agent utilisateur.
Un « proxy » est un agent de transfert de messages qui est choisi par le client, généralement au moyen de règles de configuration locales, pour recevoir les requêtes portant sur un ou plusieurs types d'URI absolus et tenter de les satisfaire par une traduction à travers l'interface HTTP. Certaines traductions sont minimes, comme pour les requêtes de proxy portant sur des URI « http », tandis que d'autres requêtes peuvent nécessiter une traduction depuis et vers des protocoles de niveau application entièrement différents. Les proxies sont souvent utilisés pour regrouper les requêtes HTTP d'une organisation à travers un intermédiaire commun, pour des raisons de sécurité, de services d'annotation ou de mise en cache partagée. Certains proxies sont conçus pour appliquer des transformations à des messages ou à des charges utiles sélectionnés pendant qu'ils sont transférés, comme décrit à la Section 5.7.2.
Une « passerelle » (aussi appelée « proxy inverse ») est un intermédiaire qui agit comme serveur d'origine pour la connexion sortante, mais qui traduit les requêtes reçues et les transmet en entrant vers un ou plusieurs autres serveurs. Les passerelles sont souvent utilisées pour encapsuler des services d'information hérités ou non fiables, pour améliorer les performances des serveurs au moyen d'une mise en cache « accélératrice », et pour permettre le cloisonnement ou l'équilibrage de charge des services HTTP sur plusieurs machines.
Toutes les exigences HTTP applicables à un serveur d'origine s'appliquent également à la communication sortante d'une passerelle. Une passerelle communique avec les serveurs entrants en utilisant le protocole qu'elle souhaite, y compris des extensions privées de HTTP qui sortent du cadre de cette spécification. Cependant, une passerelle HTTP vers HTTP qui souhaite interopérer avec des serveurs HTTP tiers devrait se conformer aux exigences applicables aux agents utilisateurs pour la connexion entrante de la passerelle.
Un « tunnel » agit comme un relais aveugle entre deux connexions, sans modifier les messages. Une fois actif, un tunnel n'est pas considéré comme une partie à la communication HTTP, bien qu'il ait pu être établi par une requête HTTP. Un tunnel cesse d'exister lorsque les deux extrémités de la connexion relayée sont fermées. Les tunnels sont utilisés pour étendre une connexion virtuelle à travers un intermédiaire, par exemple lorsque Transport Layer Security (TLS, [RFC5246]) est utilisé pour établir une communication confidentielle à travers un proxy pare-feu partagé.
Les catégories d'intermédiaires ci-dessus ne considèrent que ceux qui agissent comme participants à la communication HTTP. Il existe aussi des intermédiaires qui peuvent agir aux couches inférieures de la pile de protocoles réseau, en filtrant ou en redirigeant le trafic HTTP à l'insu ou sans l'autorisation des expéditeurs de messages. Les intermédiaires réseau sont indiscernables (au niveau du protocole) d'une attaque de l'homme du milieu, et introduisent souvent des failles de sécurité ou des problèmes d'interopérabilité en violant par erreur la sémantique de HTTP.
Par exemple, un « proxy d'interception » [RFC3040] (aussi communément appelé « proxy transparent » [RFC1919] ou « portail captif ») diffère d'un proxy HTTP parce qu'il n'est pas choisi par le client. Un proxy d'interception filtre ou redirige à la place les paquets sortants du port TCP 80 (et parfois d'autres ports courants). Les proxies d'interception se rencontrent couramment sur les points d'accès réseau publics, comme moyen d'imposer la souscription d'un compte avant d'autoriser l'usage de services Internet non locaux, ainsi qu'au sein des pare-feux d'entreprise, pour faire respecter les politiques d'usage du réseau.
HTTP est défini comme un protocole sans état, ce qui signifie que chaque message de requête peut être compris isolément. De nombreuses implémentations s'appuient sur cette conception sans état de HTTP pour réutiliser des connexions mandatées par proxy ou pour équilibrer dynamiquement les requêtes entre plusieurs serveurs. Par conséquent, un serveur MUST NOT supposer que deux requêtes d'une même connexion proviennent du même agent utilisateur, sauf si la connexion est sécurisée et propre à cet agent. Certaines extensions HTTP non standard (par exemple [RFC4559]) sont connues pour violer cette exigence, ce qui entraîne des problèmes de sécurité et d'interopérabilité.
2.4. Caches
Un « cache » est un stockage local de messages de réponse précédents, ainsi que le sous-système qui contrôle leur stockage, leur récupération et leur suppression. Un cache stocke les réponses pouvant être mises en cache afin de réduire le temps de réponse et la consommation de bande passante réseau lors de requêtes futures équivalentes. Tout client ou serveur MAY employer un cache, bien qu'un cache ne puisse pas être utilisé par un serveur lorsqu'il agit comme tunnel.
L'effet d'un cache est de raccourcir la chaîne requête/réponse si l'un des participants le long de cette chaîne dispose d'une réponse en cache applicable à cette requête. Ce qui suit illustre la chaîne résultante si B possède une copie en cache d'une réponse antérieure de O (via C) pour une requête qui n'a pas été mise en cache par UA ou par A.
> >
UA =========== A =========== B - - - - - - C - - - - - - O
< <
Une réponse est « cachable » si un cache est autorisé à stocker une copie du message de réponse en vue de répondre à des requêtes ultérieures. Même lorsqu'une réponse est cachable, le client ou le serveur d'origine peut imposer des contraintes supplémentaires sur les moments où cette réponse en cache peut être utilisée pour une requête particulière. Les exigences HTTP relatives au comportement des caches et aux réponses cachables sont définies à la Section 2 de [RFC7234].
Il existe une grande variété d'architectures et de configurations de caches déployés sur le World Wide Web et au sein de grandes organisations. Citons notamment les hiérarchies nationales de caches mandatés par proxy pour économiser la bande passante transocéanique, les systèmes collaboratifs qui diffusent ou multidiffusent des entrées de cache, les archives d'entrées de cache préchargées destinées aux environnements hors ligne ou à forte latence, et ainsi de suite.
2.5. Conformité et gestion des erreurs
Cette spécification vise des critères de conformité qui dépendent du rôle d'un participant à la communication HTTP. Ainsi, les exigences HTTP s'appliquent aux expéditeurs, destinataires, clients, serveurs, agents utilisateurs, intermédiaires, serveurs d'origine, proxies, passerelles ou caches, selon le comportement que l'exigence cherche à contraindre. Des exigences (sociales) supplémentaires s'appliquent aux implémentations, aux propriétaires de ressources et aux enregistrements d'éléments de protocole lorsqu'elles dépassent le cadre d'une seule communication.
Le verbe « generate » est utilisé à la place de « send » lorsqu'une exigence établit une distinction entre créer un élément de protocole et simplement transférer vers l'aval un élément reçu.
Une implémentation est considérée comme conforme si elle respecte toutes les exigences associées aux rôles qu'elle assume dans HTTP.
La conformité porte à la fois sur la syntaxe et sur la sémantique des éléments de protocole. Un expéditeur MUST NOT générer des éléments de protocole qui véhiculent un sens dont cet expéditeur sait qu'il est faux. Un expéditeur MUST NOT générer des éléments de protocole qui ne correspondent pas à la grammaire définie par les règles ABNF correspondantes. Au sein d'un message donné, un expéditeur MUST NOT générer des éléments de protocole ni des variantes syntaxiques qui ne sont autorisés à être générés que par des participants ayant d'autres rôles (c'est-à-dire un rôle que l'expéditeur n'a pas pour ce message).
Lorsqu'un élément de protocole reçu est analysé, le destinataire MUST être capable d'analyser toute valeur de longueur raisonnable qui est applicable au rôle du destinataire et qui correspond à la grammaire définie par les règles ABNF correspondantes. Notez toutefois que certains éléments de protocole reçus peuvent ne pas être analysés. Par exemple, un intermédiaire qui transfère un message peut analyser un champ d'en-tête en ses composants génériques field-name et field-value, puis transférer le champ d'en-tête sans pousser plus loin l'analyse à l'intérieur de la field-value.
HTTP n'impose pas de limite de longueur particulière pour beaucoup de ses éléments de protocole, car les longueurs appropriées varient très largement selon le contexte de déploiement et la finalité de l'implémentation. Par conséquent, l'interopérabilité entre expéditeurs et destinataires dépend d'attentes partagées quant à ce qu'est une longueur raisonnable pour chaque élément de protocole. En outre, ce qui est communément compris comme une longueur raisonnable pour certains éléments de protocole a changé au cours des deux décennies d'usage de HTTP, et devrait continuer à changer à l'avenir.
Au minimum, un destinataire MUST être capable d'analyser et de traiter des longueurs d'éléments de protocole au moins égales aux valeurs qu'il génère lui-même pour ces mêmes éléments de protocole dans d'autres messages. Par exemple, un serveur d'origine qui publie des références d'URI très longues vers ses propres ressources doit être capable d'analyser et de traiter ces mêmes références lorsqu'elles sont reçues comme cible de requête.
Un destinataire MUST interpréter un élément de protocole reçu selon la sémantique que lui définit cette spécification, y compris les extensions de cette spécification, sauf si le destinataire a déterminé (par l'expérience ou par sa configuration) que l'expéditeur implémente de manière incorrecte ce qu'implique cette sémantique. Par exemple, un serveur d'origine peut ne pas tenir compte du contenu d'un champ d'en-tête Accept-Encoding reçu si l'examen du champ d'en-tête User-Agent indique une version d'implémentation particulière connue pour échouer à la réception de certains codages de contenu.
Sauf indication contraire, un destinataire MAY tenter de récupérer un élément de protocole utilisable à partir d'une construction invalide. HTTP ne définit pas de mécanismes particuliers de gestion des erreurs, sauf lorsqu'ils ont un impact direct sur la sécurité, car les différentes applications du protocole nécessitent des stratégies de gestion des erreurs différentes. Par exemple, un navigateur Web peut souhaiter récupérer de manière transparente une réponse où le champ d'en-tête Location ne s'analyse pas conformément à l'ABNF, alors qu'un client de contrôle de systèmes peut considérer toute forme de récupération d'erreur comme dangereuse.
2.6. Versionnage du protocole
HTTP utilise un schéma de numérotation «
La version d'un message HTTP est indiquée par un champ HTTP-version situé dans la première ligne du message. HTTP-version est sensible à la casse.
HTTP-version = HTTP-name "/" DIGIT "." DIGIT
HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive
Le numéro de version HTTP se compose de deux chiffres décimaux séparés par un « . » (point ou séparateur décimal). Le premier chiffre (« version majeure ») indique la syntaxe de messagerie HTTP, tandis que le second chiffre (« version mineure ») indique la version mineure la plus élevée au sein de cette version majeure à laquelle l'expéditeur est conforme et qu'il est capable de comprendre pour une communication future. La version mineure annonce les capacités de communication de l'expéditeur, même lorsque celui-ci n'utilise qu'un sous-ensemble rétrocompatible du protocole, ce qui permet au destinataire de savoir que des fonctionnalités plus avancées peuvent être utilisées en réponse (par les serveurs) ou dans des requêtes futures (par les clients).
Lorsqu'un message HTTP/1.1 est envoyé à un destinataire HTTP/1.0 [RFC1945] ou à un destinataire dont la version est inconnue, le message HTTP/1.1 est construit de manière à pouvoir être interprété comme un message HTTP/1.0 valide si toutes les fonctionnalités plus récentes sont ignorées. Cette spécification impose des exigences relatives à la version du destinataire pour certaines fonctionnalités nouvelles, afin qu'un expéditeur conforme n'utilise que des fonctionnalités compatibles jusqu'à ce qu'il ait déterminé, par sa configuration ou par la réception d'un message, que le destinataire prend en charge HTTP/1.1.
L'interprétation d'un champ d'en-tête ne change pas d'une version mineure à l'autre d'une même version majeure de HTTP, bien que le comportement par défaut d'un destinataire en l'absence d'un tel champ puisse changer. Sauf spécification contraire, les champs d'en-tête définis dans HTTP/1.1 sont définis pour toutes les versions de HTTP/1.x. En particulier, les champs d'en-tête Host et Connection devraient être implémentés par toutes les implémentations de HTTP/1.x, qu'elles annoncent ou non leur conformité à HTTP/1.1.
De nouveaux champs d'en-tête peuvent être introduits sans changer la version du protocole si la sémantique qui leur est définie leur permet d'être ignorés sans danger par les destinataires qui ne les reconnaissent pas. L'extensibilité des champs d'en-tête est traitée à la Section 3.2.1.
Les intermédiaires qui traitent des messages HTTP (c'est-à-dire tous les intermédiaires autres que ceux qui agissent comme tunnels) MUST envoyer leur propre HTTP-version dans les messages transférés. Autrement dit, ils ne sont pas autorisés à transférer aveuglément la première ligne d'un message HTTP sans s'assurer que la version de protocole de ce message correspond à une version à laquelle cet intermédiaire est conforme, tant pour la réception que pour l'envoi de messages. Transférer un message HTTP sans réécrire le HTTP-version peut entraîner des erreurs de communication lorsque les destinataires en aval utilisent la version de l'expéditeur du message pour déterminer quelles fonctionnalités peuvent être utilisées sans danger lors d'une communication ultérieure avec cet expéditeur.
Un client SHOULD envoyer une version de requête égale à la version la plus élevée à laquelle le client est conforme et dont la version majeure n'est pas supérieure à la version la plus élevée prise en charge par le serveur, si celle-ci est connue. Un client MUST NOT envoyer une version à laquelle il n'est pas conforme.
Un client MAY envoyer une version de requête inférieure s'il sait que le serveur implémente incorrectement la spécification HTTP, mais uniquement après que le client a tenté au moins une requête normale et déterminé, à partir du code d'état ou des champs d'en-tête de la réponse (par exemple Server), que le serveur traite incorrectement les versions de requête supérieures.
Un serveur SHOULD envoyer une version de réponse égale à la version la plus élevée à laquelle le serveur est conforme et dont la version majeure est inférieure ou égale à celle reçue dans la requête. Un serveur MUST NOT envoyer une version à laquelle il n'est pas conforme. Un serveur peut envoyer une réponse 505 (HTTP Version Not Supported) s'il souhaite, pour quelque raison que ce soit, refuser de servir la version majeure de protocole du client.
Un serveur MAY envoyer une réponse HTTP/1.0 à une requête s'il sait ou soupçonne que le client implémente incorrectement la spécification HTTP et est incapable de traiter correctement les réponses de versions ultérieures, par exemple lorsqu'un client échoue à analyser correctement le numéro de version ou lorsqu'un intermédiaire est connu pour transférer aveuglément le HTTP-version même lorsqu'il n'est pas conforme à la version mineure donnée du protocole. De telles rétrogradations de protocole SHOULD NOT être effectuées, sauf si elles sont déclenchées par des attributs de client particuliers, par exemple lorsqu'un ou plusieurs champs d'en-tête de requête (par exemple User-Agent) correspondent de façon unique aux valeurs envoyées par un client connu pour être en erreur.
L'intention de la conception du versionnage de HTTP est que le numéro majeur ne soit incrémenté que si une syntaxe de message incompatible est introduite, et que le numéro mineur ne soit incrémenté que lorsque les modifications apportées au protocole ont pour effet d'ajouter à la sémantique des messages ou d'impliquer des capacités supplémentaires chez l'expéditeur. Cependant, la version mineure n'a pas été incrémentée pour les changements introduits entre [RFC2068] et [RFC2616], et cette révision a spécifiquement évité de tels changements du protocole.
Lorsqu'un message HTTP est reçu avec un numéro de version majeure que le destinataire implémente, mais avec un numéro de version mineure supérieur à ce que le destinataire implémente, le destinataire SHOULD traiter le message comme s'il était dans la version mineure la plus élevée au sein de cette version majeure à laquelle le destinataire est conforme. Un destinataire peut supposer qu'un message dont la version mineure est supérieure, lorsqu'il est envoyé à un destinataire qui n'a pas encore indiqué prendre en charge cette version supérieure, est suffisamment rétrocompatible pour être traité sans danger par toute implémentation de la même version majeure.
2.7. Identifiants de ressource uniformes
Les identifiants de ressource uniformes (Uniform Resource Identifier, URI) [RFC3986] sont utilisés dans tout HTTP comme moyen d'identifier des ressources (Section 2 de [RFC7231]). Les références d'URI sont utilisées pour cibler des requêtes, indiquer des redirections et définir des relations.
Les définitions de « URI-reference », « absolute-URI », « relative-part », « scheme », « authority », « port », « host », « path-abempty », « segment », « query » et « fragment » sont reprises de la syntaxe générique des URI. Une règle « absolute-path » est définie pour les éléments de protocole qui peuvent contenir un composant de chemin non vide. (Cette règle diffère légèrement de la règle path-abempty de la RFC 3986, qui autorise un chemin vide dans les références, ainsi que de la règle path-absolute, qui n'autorise pas les chemins commençant par « // ».) Une règle « partial-URI » est définie pour les éléments de protocole qui peuvent contenir une URI relative mais pas de composant fragment.
URI-reference = <URI-reference, see [RFC3986], Section 4.1>
absolute-URI = <absolute-URI, see [RFC3986], Section 4.3>
relative-part = <relative-part, see [RFC3986], Section 4.2>
scheme = <scheme, see [RFC3986], Section 3.1>
authority = <authority, see [RFC3986], Section 3.2>
uri-host = <host, see [RFC3986], Section 3.2.2>
port = <port, see [RFC3986], Section 3.2.3>
path-abempty = <path-abempty, see [RFC3986], Section 3.3>
segment = <segment, see [RFC3986], Section 3.3>
query = <query, see [RFC3986], Section 3.4>
fragment = <fragment, see [RFC3986], Section 3.5>
absolute-path = 1*( "/" segment )
partial-URI = relative-part [ "?" query ]
Chaque élément de protocole de HTTP qui autorise une référence d'URI indique dans sa production ABNF si l'élément autorise une forme quelconque de référence (URI-reference), uniquement une URI sous forme absolue (absolute-URI), uniquement les composants de chemin et de requête facultative, ou une combinaison de ce qui précède. Sauf indication contraire, les références d'URI sont analysées relativement à l'URI de requête effective (Section 5.5).
2.7.1. Schéma d'URI http
Le schéma d'URI « http » est défini par les présentes aux fins de forger des identifiants en fonction de leur association avec l'espace de noms hiérarchique régi par un éventuel serveur d'origine HTTP à l'écoute des connexions TCP ([RFC0793]) sur un port donné.
http-URI = "http:" "//" authority path-abempty [ "?" query ]
[ "#" fragment ]
Le serveur d'origine d'un URI « http » est identifié par le composant authority, qui comprend un identifiant d'hôte et un port TCP facultatif ([RFC3986], Section 3.2.2). Le composant de chemin hiérarchique et le composant de requête facultatif servent d'identifiant pour une éventuelle ressource cible au sein de l'espace de noms de ce serveur d'origine. Le composant fragment facultatif permet l'identification indirecte d'une ressource secondaire, indépendamment du schéma d'URI, comme défini à la Section 3.5 de [RFC3986].
Un expéditeur MUST NOT générer un URI « http » dont l'identifiant d'hôte est vide. Un destinataire qui traite une telle référence d'URI MUST la rejeter comme invalide.
Si l'identifiant d'hôte est fourni sous forme d'adresse IP, le serveur d'origine est l'écouteur (s'il existe) sur le port TCP indiqué à cette adresse IP. Si l'hôte est un nom enregistré, ce nom enregistré est un identifiant indirect à utiliser avec un service de résolution de noms, tel que DNS, pour trouver une adresse pour ce serveur d'origine. Si le sous-composant port est vide ou absent, le port TCP 80 (le port réservé aux services WWW) est la valeur par défaut.
Notez que la présence d'un URI doté d'un composant authority donné n'implique pas qu'un serveur HTTP soit toujours à l'écoute des connexions sur cet hôte et ce port. N'importe qui peut forger un URI. Ce que détermine le composant authority, c'est qui a le droit de répondre de manière faisant autorité aux requêtes qui visent la ressource identifiée. La nature déléguée des noms enregistrés et des adresses IP crée un espace de noms fédéré, fondé sur le contrôle de l'hôte et du port indiqués, qu'un serveur HTTP soit présent ou non. Voir la Section 9.1 pour les considérations de sécurité liées à l'établissement de l'autorité.
Lorsqu'un URI « http » est utilisé dans un contexte qui appelle un accès à la ressource indiquée, un client MAY tenter l'accès en résolvant l'hôte en une adresse IP, en établissant une connexion TCP vers cette adresse sur le port indiqué, et en envoyant au serveur un message de requête HTTP (Section 3) contenant les données identifiantes de l'URI (Section 5). Si le serveur répond à cette requête par un message de réponse HTTP non provisoire, comme décrit à la Section 6 de [RFC7231], alors cette réponse est considérée comme une réponse faisant autorité à la requête du client.
Bien que HTTP soit indépendant du protocole de transport, le schéma « http » est spécifique aux services fondés sur TCP, car le processus de délégation de noms dépend de TCP pour établir l'autorité. Un service HTTP fondé sur quelque autre protocole de connexion sous-jacent serait vraisemblablement identifié au moyen d'un schéma d'URI différent, de la même manière que le schéma « https » (ci-dessous) est utilisé pour les ressources qui nécessitent une connexion sécurisée de bout en bout. D'autres protocoles peuvent également être utilisés pour fournir l'accès à des ressources identifiées par « http » — seule l'interface faisant autorité est spécifique à TCP.
La syntaxe générique des URI pour le composant authority comprend aussi un sous-composant userinfo obsolète ([RFC3986], Section 3.2.1) destiné à inclure des informations d'authentification de l'utilisateur dans l'URI. Certaines implémentations utilisent le composant userinfo pour la configuration interne d'informations d'authentification, par exemple dans les options d'invocation de commandes, les fichiers de configuration ou les listes de favoris, même si un tel usage peut exposer un identifiant d'utilisateur ou un mot de passe. Un expéditeur MUST NOT générer le sous-composant userinfo (ni son délimiteur « @ ») lorsqu'une référence d'URI « http » est générée dans un message comme cible de requête ou comme valeur de champ d'en-tête. Avant d'utiliser une référence d'URI « http » reçue d'une source non fiable, un destinataire SHOULD rechercher la présence de userinfo et traiter celle-ci comme une erreur ; elle est probablement utilisée pour dissimuler l'autorité à des fins d'attaques d'hameçonnage.
2.7.2. Schéma d'URI https
Le schéma d'URI « https » est défini par les présentes aux fins de forger des identifiants en fonction de leur association avec l'espace de noms hiérarchique régi par un éventuel serveur d'origine HTTP à l'écoute, sur un port TCP donné, des connexions sécurisées par TLS ([RFC5246]).
Toutes les exigences énumérées ci-dessus pour le schéma « http » sont aussi des exigences pour le schéma « https », à ceci près que le port TCP 443 est la valeur par défaut si le sous-composant port est vide ou absent, et que l'agent utilisateur MUST s'assurer que sa connexion au serveur d'origine est sécurisée par l'emploi d'un chiffrement fort, de bout en bout, avant d'envoyer la première requête HTTP.
https-URI = "https:" "//" authority path-abempty [ "?" query ]
[ "#" fragment ]
Notez que le schéma d'URI « https » dépend à la fois de TLS et de TCP pour établir l'autorité. Les ressources rendues disponibles via le schéma « https » n'ont aucune identité partagée avec le schéma « http », même si leurs identifiants de ressource indiquent la même autorité (le même hôte à l'écoute du même port TCP). Ce sont des espaces de noms distincts et ils sont considérés comme des serveurs d'origine distincts. Toutefois, une extension de HTTP définie pour s'appliquer à des domaines d'hôtes entiers, comme le protocole Cookie [RFC6265], peut permettre à des informations définies par un service d'avoir un impact sur la communication avec d'autres services au sein d'un groupe correspondant de domaines d'hôtes.
Le processus d'accès faisant autorité à une ressource identifiée par « https » est défini dans [RFC2818].
2.7.3. Normalisation et comparaison des URI http et https
Étant donné que les schémas « http » et « https » sont conformes à la syntaxe générique des URI, ces URI sont normalisés et comparés selon l'algorithme défini à la Section 6 de [RFC3986], en utilisant les valeurs par défaut décrites ci-dessus pour chaque schéma.
Si le port est égal au port par défaut d'un schéma, la forme normale consiste à omettre le sous-composant port. Lorsqu'il n'est pas utilisé sous forme absolue comme cible de requête d'une requête OPTIONS, un composant de chemin vide est équivalent à un chemin absolu valant « / », de sorte que la forme normale consiste à fournir plutôt un chemin « / ». Le schéma et l'hôte sont insensibles à la casse et sont normalement fournis en minuscules ; tous les autres composants sont comparés de manière sensible à la casse. Les caractères autres que ceux de l'ensemble « reserved » sont équivalents à leurs octets encodés en pourcentage : la forme normale consiste à ne pas les encoder (voir les Sections 2.1 et 2.2 de [RFC3986]).
Par exemple, les trois URI suivants sont équivalents :
http://example.com:80/~smith/home.html
http://EXAMPLE.com/%7Esmith/home.html
http://EXAMPLE.com:/%7esmith/home.html