---
categories: ['Traduction']
date: 2020-09-16T21:19:47+02:00
description: "Traduction EN→FR : Que se passe-t-il quand vous écrivez dans la barre d'adresse du navigateur web ?!"
draft: false
tags: ['Traduction']
title: "Que se passe-t-il quand vous écrivez dans la barre d'adresse du navigateur web…"
---
## Prologue
Cet article est la traduction de l'article anglais **"[What happens when…][1]"**
d'Alex Gaynor. De même que l'article original est sous [licence CC0][2], ainsi
est la traduction de cet article.
---
## Que se passe-t-il quand…
Ce dépôt est une tentative pour répondre à cette vieille question d'interview
"Que se passe-t-il quand vous écrivez google.com dans la barre d'adresse
de votre navigateur web et que vous appuyez sur la touche Entrée ?"
Hormis l'habituel histoire, nous allons essayer de répondre à cette question
avec autant de détails que possible. Rien ne sera négligé.
Ceci est un processus collaboratif, alors svp creusez et essayez d'aider !
Il y a des tonnes de détails manquants qui n'attendent que vous pour les
ajouter ! SVP, envoyez-nous vos requêtes !
Tout ceci est sous les termes de la licence [Creative Commons Zero][2]
Vous pouvez lire ceci en [简体中文][10] (Chinois simplifié), [日本語][11] (Japonais)
et [한국어][12] (Coréen). NOTE : ces traductions n'ont pas été examinées par les
responsables de alex/what-happens-when.
---
### La touche "g" est appuyée
La section suivante explique les actions physiques du clavier et les
interruptions du système d'exploitation. Lorsque vous appuyez sur la touche
g, le navigateur reçoit l'événement et les fonctions d'autocomplétion
s'enclenchent.
Selon l'algorithme de votre navigateur et si vous êtes en mode privé, ou
non, diverses suggestions vous seront présentées dans un menu déroulant
sous la barre d'{{< abbr URL "Uniform Resource Locator" >}}. La plupart
des algorithmes trient et priorisent les résultats selon la recherche historique,
les marques-pages, les cookies, et les recherches populaires sur Internet.
Lorsque vous écrivez google.com, de nombreux blocs de code s'exécutent
et les suggestions seront affinées à chaque appui sur une touche. Il peut
même vous suggérer "google.com" avant que vous ayez fini de l'écrire.
### L'appui sur la touche "Entrée"
Pour commencer, choisissons l'appui sur le bas de la touche Entrée.
À ce moment, un circuit électrique spécifique à la touche est verrouillée
(soit directement, soit de manière capacitive). Ceci permet à une petite
quantité de courant de circuler dans le circuit logique du clavier, qui
analyse l'état de l'interrupteur de chaque touche, élimine le bruit électrique
de la fermeture intermittente rapide de l'interrupteur et le convertit en
un entier de code de touche, en l’occurrence 13.
Le contrôleur du clavier encode alors le code de touche pour le transport
vers l'ordinateur. Actuellement, c'est presque universellement au-travers
d'une connexion {{< abbr USB "Universal Serial Bus" >}} ou par Bluetooth,
mais historiquement c'était des connexions de type [{{< abbr PS "Personal System" >}}/2][20]
ou [{{< abbr ADB "Apple Desktop Bus" >}}][21].
*Dans le cas d'un clavier USB :*
- Le circuit USB du clavier est alimenté par l'alimentation 5{{< abbr V "volt" >}}
fournit sur la broche 1 du contrôleur USB de l'ordinateur.
- Le code de touche généré est enregistré par la mémoire du circuit interne
du clavier dans un registre appelé "endpoint".
- Le contrôleur USB analyse ce registre "endpoint" environ toutes les 10
millisecondes *(valeur minimum déclarée par le clavier)*, ainsi il
enregistre la valeur du code de touche.
- Cette valeur parvient au moteur d'interface série USB {{< abbr SIE "Serial Interface Engine" >}}
afin d'être converti dans un ou plusieurs paquets USB selon le protocole
USB de bas niveau.
- Ces paquets sont envoyés par un signal électrique différentiel sur les
connecteurs D+ et D- (entre 2) à la vitesse maximale de 1.5 {{< abbr "Mo/s" "Méga-octet par seconde" >}},
puisqu'un dispositif [{{< abbr IHM "Interface Homme-Machine" >}}][22] est
toujours déclaré en tant que "dispositif à faible vitesse"
*(en conformité avec la norme USB 2.0)*.
- Ce signal en série est alors décodé par le contrôleur USB de l'ordinateur,
puis interprété par le pilote du dispositif universel de clavier IHM
de l'ordinateur. La valeur de la touche est passée au-travers de la
couche d'abstraction matérielle du système d'exploitation.
*Dans le cas d'un clavier virtuel (de même pour les écrans tactiles) :*
- Quand l'utilisateur pose son doigt sur un écran tactile capacitif moderne,
une quantité infime de courant est transmise au doigt. Cela complète
le circuit par le champ électrostatique de la couche conductrice et
crée une chute de tension à cet endroit de l'écran. Le **contrôleur de l'écran**
lève une interruption rapportant les coordonnées de la touche pressée.
- Alors le système d'exploitation mobile notifie à l'application en cours
de l’événement de pression d'un des éléments de son interface *(qui sont
les boutons de l'interface virtuelle de l'application de clavier)*.
- Le clavier virtuel peut maintenant lever une interruption logicielle
afin d'envoyer un message de 'touche pressée' au système d'exploitation.
- Cette interruption notifie l'application en cours d'un événement de 'touche
pressée'.
### Déclenchement d'interruption [Hors claviers USB]
Le clavier envoie des signaux sur sa ligne de requêtes d'interruption *([{{< abbr IRQ "Interrupt ReQuest" >}}][30])*,
qui correspond à un entier ``interrupt vector`` du contrôleur d'interruption.
Le processeur ([{{< abbr UCT "Unité Centrale de Traitement" >}}][31]) utilise
la table de descripteurs d'interruptions ([{{< abbr IDT "Interrupt Descriptor Table" >}}][32])
qui correspond aux vecteurs d'interruptions vers les fonctions *(``interrupt handlers``)*
qui sont fournis par le noyau. Lorsqu'une interruption arrive, l'UCT indexe
l'IDT avec le vecteur d'interruptions et exécute le gestionnaire approprié.
Ainsi, le noyau est introduit.
### (Dans Windows) Un message ``WM_KEYDOWN`` est envoyé à l'application
Le transport IHM envoie l'événement de touche pressée au pilote ``KBDHID.sys``
qui convertit l'utilisation de l'IHM vers un code d'analyse.
Dans ce cas, le code d'analyse est ``VK_RETURN`` *(``0x0D``)*.
Le pilote ``KBDHID.sys`` s'interface avec ``KBDCLASS.sys`` *(un pilote de classe clavier)*.
Ce pilote est responsable de toutes les entrées de clavier et clavier numérique de
manière sécurisée. Il les appelle ensuite dans ``Win32K.sys`` *(après avoir
passer le message dans les filtres de clavier tiers installés)*.
C'est tout ce qui se passe dans le noyau.
``Win32K.sys`` détermine quelle fenêtre est active au-travers de l'[{{< abbr API "Interface de Programmation Applicative" >}}][40]
``GetForegroundWindow()``. Cette API fournit la capture de la fenêtre à
la boite d'adresse du navigateur.
La fenêtre principale "message pump" appelle alors ``SendMessage(hWnd, WM_KEYDOWN, VK_RETURN, lParam)``.
``lParam`` est un masque binaire qui indique des informations complémentaires
à la pression de touche : compteur de répétition *(`0` dans ce cas)*, le code d'analyse actuel
*(peut être dépendant du fabriquant, mais ne l'est pas généralement pour ``VK_RETURN``)*,
quelque soit la touche étendue *(e.g. alt, shift, ctrl)* qui soit aussi
appuyée *(elles ne l'étaient pas)*, ou dans un autre état.
L'API Windows ``SendMessage`` est une fonction simple qui ajoute le message
à une queue d'un gestionnaire de fenêtres particulier *(``hWnd``)*. Plus tard,
la fonction principale de traitement des messages *(appelée ``WindowProc``)*
assignée à ``hWnd`` est appelée afin de traiter chaque message dans la queue.
La fenêtre *(``hWnd``)* qui est active est en fait un contrôleur d'édition,
et le ``WindowProc`` dans ce cas est un gestionnaire de messages pour ``WM_KEYDOWN``.
Ce code cherche un paramètre tiers qui est passé à ``SendMessage`` *(``wParam``)*,
parce que ``VK_RETURN`` sait qu'un utilisateur a appuyé sur la touche Entrée.
### (Dans OS X) Un NSEvent ``KeyDown`` est envoyé à l'application
Le signal d'interruption déclenche un événement d'interruption dans le pilote
du Kit d'Entrée/Sortie (I/O) kext du clavier. Le pilote traduit le signal
dans un code de touche qui est passée au process d'OS X ``WindowServer``.
Pour résultat, le ``WindowServer`` envoie un événement à toute application
appropriée *(e.g. active ou écoutant)* au-travers du port Mach qui est placé
dans la queue d'événements. Les événements peuvent alors être lus depuis
cette queue par des "fils" *(appelés threads)* disposant des privilèges
suffisants appelant la fonction ``mach_ipc_dispatch``.
Cela arrive généralement au-travers d'une boucle de gestion principale ``NSApplication``
le gérant, via un événement ``NSEvent`` d'un type d'événement ``NSEventType`` ``KeyDown``.
### (Dans GNU/Linux) Le serveur Xorg écoute les codes de touches
Lorsqu'un serveur graphique ``X server`` est utilisé, ``X`` utilisera
le pilote d'événement générique ``evdev`` afin d'acquérir l'événement de
pression de touche. La conversion des codes de touches en codes d'analyse
est faite à l'aide de règles et de keymaps *("cartes de claviers")* spécifiques
à ``X server``.
Lorsque la correspondance du code d'analyse à une touche pressée est complète,
le ``X server`` envoie le caractère au gestionnaire de fenêtres ``window manager``
*(DWM, metacity, i3, etc)*, afin que le ``window manager`` à son tour envoie
le caractère à la fenêtre en cours.
L'API graphique de la fenêtre qui reçoit le caractère affiche le symbole
de police approprié dans le champ approprié ayant le focus.
### Analyse d'URL
* Le navigateur a maintenant l'information suivante contenue dans l'[{{< abbr URL "Uniform Resource Locator" >}}][70] :
- **Protocole** "http" : Utilise "[{{< abbr HTTP "Hyper Text Transfer Protocol" >}}][71]"
- **Ressource** "/" : Récupère la page principale (index)
### Est-ce une URL ou un terme recherché ?
Quand aucun protocole ou nom de domaine valide n'est donné, le navigateur
s'occupe de récupérer le texte donné dans la boite d'adresse au moteur de
recherche web par défaut du navigateur.
Dans beaucoup de cas, un texte spécial est ajouté à l'URL pour indiquer
au moteur de recherche qu'il provient de la barre d'URL d'un navigateur
particulier.
### Convertir les caractères Unicode non-ASCII dans le nom d'hôte
* Le navigateur vérifie tous les caractères du nom d'hôte, qui ne soient pas
``a-z``, ``A-Z``, ``0-9``, ``-``, ou ``.``.
* Puisque le nom d'hôte est ``google.com``, il n'y en aura pas ; mais si
c'était le cas, le navigateur appliquerait l'encodage [Punycode][80] à la
portion du nom d'hôte dans l'URL.
### Vérifier la liste HSTS
* Le navigateur vérifie sa liste de "[{{< abbr HSTS "HTTP Strict Transport Security" >}}][90] préchargés".
C'est une liste de sites web qui ont requis de n'être contactés seulement
que sur [{{< abbr HTTPS "HyperText Transfer Protocol Secure" >}}][91].
* Si le site web est dans la liste, le navigateur envoie sa requête via
HTTPS plutôt qu'en HTTP. Autrement, la requête initiale est envoyée en HTTP.
*(Notez qu'un site web peut toujours utiliser une politique HSTS *sans*
être dans la liste HSTS. La première requête HTTP au site web faite par
un utilisateur recevra une réponse demandant que l'utilisateur envoie
seulement des requêtes HTTPS. Toutefois, cette unique requête HTTP
pourrait potentiellement laisser l'utilisateur vulnérable à une attaque dite
[`downgrade attack`][92] ; c'est la raison pour laquelle la liste HSTS est
incluse dans les navigateurs web modernes)*.
### Recherche DNS
* Le navigateur vérifie si le domaine est dans son cache. *(Pour voir le
cache DNS dans Chrome, écrivez dans la barre d'adresse
`chrome://net-internals/#dns`)*.
* S'il n'est pas trouvé, le navigateur appelle la fonction de bibliothèque
``gethostbyname`` *(qui varie selon l'OS)* afin de faire la recherche.
* ``gethostbyname`` vérifie si le nom d'hôte peut être résolu par référence
dans le fichier local ``hosts`` *(dont la localisation [varie selon l'OS][100])*
avant d'essayer de résoudre le nom d'hôte au-travers [{{< abbr DNS "Domain Name System" >}}][101].
* Si ``gethostbyname`` ne le trouve pas dans le cache, ni dans le fichier ``hosts``
alors elle fait une requête vers le serveur DNS configuré dans la pile
réseau. C'est typiquement le routeur local ou le serveur DNS cache du
[{{< abbr FAI "Fournisseur Accès Internet" >}}][102].
* Si le serveur DNS est sur le même sous-réseau, la bibliothèque réseau
suit le ``processus ARP`` décrit ci-dessous pour le serveur DNS.
* Si le serveur DNS est sur un sous-réseau différent, la bibliothèque réseau
suit le ``processus ARP`` décrit ci-dessous pour l'adresse IP de la
passerelle par défaut.
### Processus ARP
Avant d'envoyer une diffusion [{{< abbr ARP "Address Resolution Protocol" >}}][110],
la bibliothèque de la pile réseau a besoin de l'[adresse {{< abbr IP "Internet Protocol" >}}][111]
cible à rechercher. Elle doit aussi connaître l'[adresse {{< abbr MAC "Media Access Control" >}}][112]
de l'interface qu'elle utilisera pour envoyer la diffusion ARP.
Le cache ARP est vérifié en premier pour trouver une entrée ARP de notre
IP cible. Si elle est dans le cache, la bibliothèque retourne le résultat :
IP cible = MAC.
Si l'entrée n'est pas dans le cache ARP :
* La table de routage est recherchée, pour voir si l'adresse IP ciblée est
dans le sous-réseau de la table de routage local. Si elle y est, la
bibliothèque utilise l'interface associée au sous-réseau. Si elle n'y
est pas, la bibliothèque utilise l'interface qui est dans le sous-réseau
de notre passerelle par défaut.
* L'adresse MAC de l'interface réseau sélectionnée est recherchée.
* La bibliothèque réseau envoie une {{< anchor "requête ARP" "Requête ARP">}} de la Couche de Liaison 2
*(trame de liaison d'adressage physique du [modèle OSI][113])* :
#### Requête ARP
* Émetteur MAC: `interface:mac:address:here`
* Émetteur IP: `interface.ip.goes.here`
* Cible MAC: `FF:FF:FF:FF:FF:FF` *(Broadcast)*
* Cible IP: `target.ip.goes.here`
Cela dépend du type de matériel qui est entre l'ordinateur et le routeur :
⇒ Directement connecté :
* Si l'ordinateur est directement connecté au routeur, le routeur répond
avec une "{{< anchor "réponse ARP" "Réponse ARP" >}}" *(lire ci-dessous)*
⇒ Par un Hub :
* Si l'ordinateur est connecté à un hub, le hub diffusera la requête ARP
vers tous les autres ports. Si le routeur est connecté sur la même "interface",
il répondra avec une "{{< anchor "réponse ARP" "Réponse ARP" >}}" *(lire ci-dessous)*.
⇒ Par un commutateur :
* Si l'ordinateur est connecté à un commutateur, le commutateur vérifiera
sa table MAC pour savoir sur quel port est diffusé l'adresse MAC recherchée.
Si le commutateur n'a pas d'entrée pour l'adresse MAC, il rediffusera
la requête ARP vers tous les autres ports.
* Si le commutateur a une entrée dans la table MAC, il enverra une requête
ARP au port correspondant à l'adresse MAC recherchée.
* Si le routeur est sur la même "interface", il répondra avec une "{{< anchor "réponse ARP" "Réponse ARP" >}}"
*(lire ci-dessous)*
#### Réponse ARP
* Émetteur MAC: `target:mac:address:here`
* Émetteur IP: `target.ip.goes.here`
* Cible MAC: `interface:mac:address:here`
* Cible IP: `interface.ip.goes.here`
---
*Le protocole ARP est nécessaire au fonctionnement d’[IPv4][114], utilisé par dessus
un réseau de type Ethernet. En [IPv6][115], les fonctions ARP ont été reprises dans
le processus de découverte [{{< abbr NDP "Neighbor Discovery Protocol" >}}][116]*
---
Maintenant que la bibliothèque réseau a l'adresse IP, soit de notre serveur
DNS, soit de la passerelle par défaut, elle peut reprendre son processus DNS :
* Le client DNS établit un socket vers le port UDP 53 du serveur DNS, utilisant
un port source au-delà de 1023.
* Si la taille de la réponse est trop grande, TCP sera utilisé à la place.
* Si le serveur DNS local ou du FAI ne l'a pas, alors une recherche récursive
est requise et fait remonter la liste des serveurs DNS, et qu'une réponse
soit retournée.
### Ouverture d'une socket
Une fois que le navigateur reçoit l'adresse IP du serveur de destination,
il la prend ainsi que le numéro de port donné dans l'URL *(par défaut, le
protocole HTTP a le port 80, et HTTPS le port 443)*, puis fait un appel à
la fonction de la bibliothèque système nommée ``socket`` et requiert un
flux de socket TCP - ``AF_INET/AF_INET6`` et ``SOCK_STREAM``.
* Cette requête est en premier passé à la Couche de Transport où un segment
TCP est créé. Le port de destination est ajouté à l'entête, et le port
source est choisi parmi une plage de port dynamique du noyau
*(`ip_local_port_range` dans Linux)*.
* Ce segment est envoyé vers la Couche Réseau, qui enveloppe une entête IP
additionnelle. L'adresse IP du serveur cible aussi bien que celle de
la machine courante est insérée pour former un paquet.
* Le paquet suivant arrive sur la Couche de Liaison. Une entête de trame
est ajouté qui inclut l'adresse MAC de l'interface réseau de la machine
ainsi que l'adresse MAC de la passerelle *(le routeur local)*. Tout comme
avant, si le noyau ne connaît pas l'adresse MAC de la passerelle, il
doit diffuser une requête ARP pour la trouver.
À partir de ce point, le paquet est prêt à être transmis, soit au-travers :
* [Ethernet][120]
* [WiFi][121]
* [Réseau de Téléphonie Mobile][122]
Pour la plupart des connexions à Internet depuis une maison, ou pour de
petites entreprises, le paquet passera de votre ordinateur, possiblement
au-travers du réseau local, puis vers un {{< abbr modem "MOdulateur/DEModulateur" >}}
qui convertit les 0 et 1 numériques en signal analogique adapté à la
transmission par téléphone, câble ou connexions de téléphonie sans fil.
À l'autre extrémité de la connexion se trouve un autre modem qui reconvertit
le signal analogique en données numériques qui seront traitées par le
prochain [nœud de réseau][123] où les adresses de départ et d'arrivée seront
analysées plus en détail.
La plupart des grandes entreprises et certaines connexions résidentielles
plus récentes disposeront de connexions en fibre optique ou de connexions
Ethernet directes, auxquels cas les données restent numériques et sont
transmises directement au prochain [nœud de réseau][123] pour y être traitées.
Éventuellement, le paquet atteindra le routeur gérant le sous-réseau local.
Depuis là, il continuera à voyager vers l'[{{< abbr AS "système autonome" >}}][124] au-delà
du routeur, vers d'autres AS, et finalement atteindra le serveur de destination.
Chaque routeur, le long du chemin, extrait l'adresse de destination de
l'entête d'IP et la dirige vers le prochain saut approprié.
Le champ [{{< abbr TTL "Time to Live" >}}][125] dans l'entête de l'IP est décrémenté
de un à chaque routeur traversé. Le paquet sera supprimé si le champ TTL
atteint zéro ou si le routeur en cours n'a plus d'espace dans sa queue
*(cela peut être dû à une congestion du réseau)*.
Cet envoi et cette réception arrive de nombreuses fois suivant le flux de
connexion TCP :
* Le client choisit un [{{< abbr ISN "numéro de séquence initial" >}}][126]
et envoie le paquet au serveur avec le bit SYN paramétré pour indiquer
qu'il active l'ISN.
* Le serveur reçoit le bit SYN et s'il est "d'humeur agréable" :
* le serveur choisit son propre numéro de séquence initial
* le serveur paramètre le bit SYN afin d'indiquer qu'il a choisit son ISN
* le serveur copie l'ISN du client +1 dans son champ ACK et ajoute le
drapeau ACK afin d'indiquer qu'il accuse réception du premier paquet.
* Le client reconnaît la connexion en envoyant un paquet :
* augmentant son propre numéro de séquence
* augmentant le numéro d'accusé de réception
* paramètre le champ ACK
* La donnée est transmise ainsi :
* Lorsqu'une partie envoie N octets de données, elle augmente sa séquence
SEQ par un numéro
* Quand l'autre partie accuse réception du paquet (ou d'une chaîne de
paquets), elle envoie un paquet ACK avec une valeur ACK égale à la
dernière séquence reçue depuis l'autre partie.
* Pour fermer la connexion :
* la partie qui termine la connexion envoie un paquet FIN.
* l'autre partie accuse réception ACK du paquet FIN et envoie son propre
paquet FIN.
* la première partie accuse réception ACK du paquet FIN de l'autre partie.
### La Poignée de Main TLS
* L'ordinateur client envoie un message ``ClientHello`` au serveur avec sa
version de [{{< abbr TLS "Transport Layer Security" >}}][130], une liste
d'algorithmes de chiffrement et de méthodes de compression disponibles.
* Le serveur répond avec un message ``ServerHello`` au client avec la version
TLS, le chiffrement choisi, les méthodes de compression sélectionnées et
le certificat public signé par une [{{< abbr AC "Autorité de Certification" >}}][131] du serveur.
Le certificat contient une clé publique qui sera utilisée par le client
pour chiffrer le reste de la poignée de main jusqu'à ce qu'une clé symétrique
puisse être convenue.
* Le client vérifie que le certificat numérique du serveur soit dans sa
liste d'AC de confiance. Si la confiance peut être établie, basée sur
l'AC, le client génère une chaîne d'octets pseudo-aléatoires et la
chiffre avec la clé publique du serveur. Ces octets aléatoires peuvent
être utilisés pour déterminer la clé symétrique.
* Le serveur déchiffre les octets aléatoires en utilisant sa clé privée
puis utilise ces octets pour générer sa propre copie de la clé symétrique
maître.
* Le client envoie un message ``Finished`` au serveur, chiffrant un hash
de la transmission jusqu'à ce point avec la clé symétrique.
* Le serveur génère son propre hash, puis déchiffre le hash envoyé par le
client pour vérifier la correspondance. Si elle existe, il envoie son
propre message ``Finished`` au client, le chiffrant aussi avec sa clé
symétrique.
* À partir de maintenant la session TLS transmet les données de l'application
*(HTTP)* chiffrées avec la clé symétrique agréée.
### Protocole HTTP
Si le navigateur web utilisé été écrit par Google, au lieu d'envoyer une
requête HTTP pour récupérer la page, il enverra une requête pour négocier
avec le serveur une "mise à jour" du protocole HTTP vers le protocole [{{< abbr SPDY Speedy >}}][140].
Si le client utilise le protocole HTTP mais ne prend pas en charge SPDY,
il envoie une requête au serveur de la forme :
GET / HTTP/1.1
Host: google.com
Connection: close
[autres entêtes]
où ``[autres entêtes]`` référent à une série de paire de clé et valeur séparée
par le symbole deux points ':', formatées selon la spécification HTTP et
séparées par d'uniques nouvelles lignes.
*(Cela suppose que le navigateur web utilisé n'ait pas de bogues violant la
spécification HTTP. Cela suppose aussi que le navigateur web utilise ``HTTP/1.1``,
autrement il ne pourrait pas inclure l'entête ``Host`` dans la requête ;
la version spécifiée dans la requête ``GET`` serait soit ``HTTP/1.0`` ou ``HTTP/0.9``.)*
HTTP/1.1 définit l'option de "fermeture" de la connexion pour que l'expéditeur
signale que la connexion sera fermée après l'achèvement de la réponse.
Par exemple :
Connection: close
Les applications HTTP/1.1 qui ne prennent pas en charge les connexions
persistantes DOIVENT inclure l'option de "fermeture" de connexion dans
chaque message.
Après l'envoi de la requête et des entêtes, le navigateur web envoie une
unique nouvelle ligne vierge pour indiquer au serveur que le contenu de
la requête est fait.
Le serveur répond avec un code de réponse dénotant le statut de la requête
et avec une réponse de la forme :
200 OK
[entêtes de réponse]
Suivies d'une unique nouvelle ligne, il envoie alors la charge du contenu
HTML de ``www.google.com``. Le serveur peut alors soit fermer la connexion,
soit si les entêtes envoyées par le client le demande, garder la connexion
ouverte afin d'être réutilisées pour de prochaines requêtes.
Si les entêtes HTTP envoyées par le navigateur web comportent des informations
suffisantes pour que le serveur web détermine si la version du fichier en
cache dans le navigateur web n'a pas été modifié depuis la dernière récupération
*(tel que si le navigateur web inclut une entête ``ETag``)*, il peut alors
répondre par une requête de la forme :
304 Not Modified
[entêtes de réponse]
il n'y aura pas charge utile, et le navigateur web récupérera le HTML depuis
son cache.
Après l'analyse du HTML, le navigateur web *(ainsi que le serveur)* répétera
ce processus pour chaque ressource *(image, CSS, favicon.ico, etc)* référencée
dans la page HTML, excepté que la requête sera ``GET /$(URL relative à www.google.com) HTTP/1.1``
au lieu de ``GET / HTTP/1.1``.
Si le HTML référence une ressource sur un domaine différent que ``www.google.com``,
le navigateur web reprendra les étapes invoquées pour résoudre l'autre domaine,
et suivra toutes les mêmes étapes jusqu'à ce point pour ce domaine.
L'entête ``Host`` dans la requête sera paramétrée vers le nom du serveur
approprié plutôt que ``google.com``.
### Gestionnaire de Requêtes HTTP du Serveur
Le serveur HTTPD *(Service HTTP)* est un gestionnaire de requêtes et de réponses
côté serveur. Les serveurs HTTPD des plus communs sont Apache ou nginx pour
Linux et IIS pour Windows.
* Le serveur HTTPD *(Service HTTP)* reçoit la requête.
* Le serveur décompose la requête selon les paramètres suivants :
* la méthode de requête HTTP *(soit ``GET``, ``HEAD``, ``POST``, ``PUT``,
``PATCH``, ``DELETE``, ``CONNECT``, ``OPTIONS``, ou ``TRACE``)*. Dans
le cas où l'URL est entrée directement dans la barre d'adresse, elle
sera ``GET``.
* le domaine ; dans ce cas : google.com
* le chemin ou la page demandé ; dans ce cas : / *(puisqu'il n'y a pas
de chemin ou de page spécifique demandé, / est le chemin par défaut)*.
* Le serveur vérifie qu'un Hôte Virtuel soit configuré sur le serveur correspondant
à google.com.
* Le serveur vérifie que google.com peut accepter les requêtes GET.
* Le serveur vérifie que le client est autorisé à utiliser cette méthode
*(par l'adresse IP, authentification, etc)*.
* Si le serveur a un module de ré-écriture installé *(tel que mod_rewrite
pour Apache ou URL Rewrite pour IIS)*, il essaiera la correspondance de
la requête avec une des règles configurées. Si une règle correspondante
est trouvée, le serveur utilise la règle pour ré-écrire la requête.
* Le serveur envoie le contenu qui correspond à la requête, dans notre cas,
il reviendra au fichier index, puisque "/" est le fichier principal
*(dans certains cas, cela peut être surchargé, mais c'est la méthode commune)*.
* Le serveur analyse le fichier en accord avec le gestionnaire. Si Google
exécute PHP, le serveur utilise PHP pour interpréter le fichier index,
et envoie le flux vers le client.
### La scène derrière le Navigateur
Une fois que le serveur délivre les ressources *(HTML, CSS, JS, images, etc)*
au navigateur, il est soumis au processus suivant :
* Analyse HTML, CSS, JS
* Rendu : construit l'arborescence DOM → l'arborescence de rendu → le plan
de l'arborescence de rendu → l'affichage de l'arborescence de rendu
### Le Navigateur
La fonction du navigateur est de présenter la ressource web que vous avez
choisi, en la demandant à un serveur et en l'affichant dans la fenêtre du
navigateur. La ressource est habituellement un document HTML, mais peut
être aussi un PDF, une image, ou tout autre type de contenu. L'endroit de
la ressource est spécifié par l'utilisateur selon une {{< abbr URI "Uniform Resource Identifier" >}}.
La manière dont le navigateur interprète et affiche les fichiers HTML est
spécifiée dans les spécifications HTML et CSS. Ces spécifications sont
maintenues par le {{< abbr W3C "World Wide Web Consortium" >}}, qui est
l'organisation des standards du web.
Les interfaces utilisateur de navigation ont beaucoup en commun entre elles.
Parmi les éléments communs de l'interface utilisateur, on peut citer :
* une barre d'adresse pour l'insertion d'une URI
* des boutons de retour et d'avance
* des options de marque-pages *(favoris)*
* des boutons pour rafraîchir et stopper le chargement de documents en cours
* un bouton d’accueil pour vous permettre d'aller à votre page d'accueil.
**Structure de Haut Niveau du Navigateur**
Les composants des navigateurs sont :
* **Une Interface Utilisateur** : l'interface utilisateur *(UI)* inclue la barre
d'adresse, les boutons retour/avance, le menu des marque-pages, etc.
Chaque partie du navigateur s'affiche, exceptée la fenêtre où vous voyez
la page demandée.
* **Le Moteur du Navigateur** : le moteur du navigateur répartit les actions
entre l'UI et le moteur de rendu.
* **Le Moteur de Rendu** : le moteur de rendu est responsable d'afficher
le contenu demandé. Par exemple, si le contenu demandé est du HTML, le
moteur de rendu analyse le HTML et le CSS, et affiche le contenu analysé
à l'écran.
* **Réseau** : le réseau gère les appels réseau tels que les requêtes HTTP,
utilisant différentes implémentations pour les différentes plateformes
derrière une interface de plateforme indépendante.
* **Backend UI** : le backend de l'UI est utilisé pour dessiner
les widgets basiques tels que les comboboxes et les fenêtres. Ce backend
expose une interface générique qui n'est pas spécifique à une plateforme.
En profondeur, il utilise les méthodes de l'interface utilisateur du
système d'exploitation.
* **Le Moteur JavaScript** : le moteur JavaScript est utilisé pour analyser
et exécuter le code JavaScript.
* **Le Stockage des Données** : le stockage des données est une couche persistante.
Le navigateur peut sauvegarder toute sorte de données localement, tels
que des cookies. Les navigateurs prennent en charge aussi des mécanismes
de stockage tels que localStorage, IndexedDB, WebSQL et FileSystem.
### Analyse du HTML
Le moteur de rendu démarre l'obtention des contenus du document demandé
depuis la couche réseau. Cela se fait habituellement par morceaux de 8 Ko.
Le premier travail de l'analyseur HTML est d'analyser le langage HTML dans
une arborescence.
La sortie de l'arborescence *("l'arborescence analysée")* est une arborescence
des éléments du DOM et des nœuds d'attributs. DOM est l'abréviation de
Document Object Model. C'est la présentation objet du document HTML et
l'interface des éléments HTML au monde extérieur tel JavaScript.
La racine de l'arborescence est l'objet "Document".
Avant toute manipulation par script, le DOM a une relation quasi-univoque
avec le balisage.
**Algorithme d'Analyse**
Le HTML ne peut être analysé par des analyseurs habituels.
Les raisons sont :
* la nature indulgente du langage.
* le fait que les navigateurs ont une tolérance traditionnelle à l'erreur
pour prendre en charge les cas connus de HTML invalides.
* le processus d'analyse est ré-entrant. Pour les autres langages, la source
ne change pas durant l'analyse, mais en HTML, le code dynamique *(tels
que des éléments de scripts contenant des appels à `document.write()`)*
peut ajouter des jetons supplémentaires ; le processus d'analyse en cours
modifie alors l'entrée.
Si le navigateur est incapable d'utiliser les techniques d'analyses régulières,
il utilisera un analyseur personnalisé pour l'analyse HTML. L'algorithme
d'analyse est décrit en détail par la spécification HTML5.
L'algorithme consiste en deux phases : mise en jeton et construction de
l'arborescence.
**Les Actions lorsque l'Analyse est terminée**
Le navigateur commence par récupérer les ressources externes liées à la page
*(CSS, images, fichiers JavaScript, etc)*.
Lors de cette étape, le navigateur marque le document comme interactif et
démarre les scripts d'analyse qui sont dans le mode "différé" : tout ce
qui doit être exécuté après le document est analysé. L'état du document
est paramétré sur "complet" et un événement "charge" est levé.
Notez qu'il n'y a jamais d'erreur "Invalid Syntax" sur une page HTML.
Les navigateurs corrigent tout contenu invalide et l'envoie.
### Interprétation du CSS
* Analyse des fichiers CSS, du contenu des balises ``