HTTP : la négociation de contenu¶
La forme des messages échangés entre un client et un serveur n’est absolument pas prescrite par HTTP. Par forme, il faut comprendre aussi bien le format, le jeu de caractères (charset) mais aussi la langue utilisée (s’il s’agit d’une forme textuelle). On dit que le client et le serveur n’échangent que des représentations. Différents clients et serveurs peuvent avoir des capacités ou des préférences différentes concernant la forme d’une représentation. HTTP définit ainsi la possibilité de décrire le contenu d’un message grâce aux en-têtes Content-type et Content-Language. Mais HTTP permet aussi à un client et à un serveur de se mettre d’accord sur la forme de représentation souhaitée. Ce mécanisme s’appelle la négociation de contenu. On distingue deux méthodes de négociation de contenu :
- La négociation proactive
- Le serveur sélectionne la représentation la plus appropriée en fonction des préférences du client que ce dernier transmet dans la requête.
- La négociation réactive
- Le serveur répond à un client non pas une représentation, mais une liste de liens vers des représentations en précisant la forme de chacune. Le client peut alors choisir parmi cette liste la représentation qui lui convient le mieux.
Dans la suite de ce chapitre, nous nous bornerons à détailler la négociation de contenu proactive.
La négociation de type de contenu¶
Parfois, un serveur peut disposer de plusieurs représentations pour une
même ressource. Par exemple, il peut présenter un série de données dans
une page HTML et sous un format CSV. Le client peut alors suggérer au
serveur une liste de formats MIME correspondant à ses préférences.
L’en-tête
Accept permet
au client de fournir une liste de types MIME séparés par une virgule.
Bien évidemment, l’en-tête Accept
n’a de sens que si le client
s’attend à recevoir une représentation de la part du serveur (ou s’il
utilise la méthode HEAD
pour tester l’existence de ce format).
Négociation de contenu sur le type de représentation
GET /individu/00001 HTTP/1.1
Host: www.monserveur.fr
Accept: text/html,text/plain,application/pdf
Dans l’exemple précédent, l’ordre dans la liste n’a pas d’importance, le client annonce au serveur qu’il peut indifféremment fournir une représentation au format HTML, texte brut ou un document PDF. Si le serveur ne peut fournir aucune de ces représentations, il doit considérer qu’il ne peut pas fournir de réponse acceptable pour ce client. Dans ce cas, le serveur peut :
- Répondre par un code statut 406 (Not Acceptable)
- Ignorer l’en-tête et retourner une représentation de son choix. En effet, on considère que la décision de traiter ou non la réponse revient en dernier lieu au client.
Le client peut affiner sa négociation en annonçant que si plusieurs
représentations sont disponibles, certaines seront préférées à d’autres.
Cela se fait à l’aide du paramètre q (quality value) qui donne une
pondération entre 0 et 1. Lorsque le paramètre q
n’est pas précisé,
sa valeur implicite est 1 (la plus forte préférence). Une valeur de 0
signifie que la représentation associée n’est pas acceptable pour ce
client.
Négociation de contenu avec pondération des formats
GET /individu/00001 HTTP/1.1
Host: www.monserveur.fr
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Dans l’exemple précédent, le client annonce au serveur qu’il préfére les
formats HTML et XHTML (q=1 est ici implicite) au format XML simple
(q=0.9). Sinon il accepte de recevoir n’importe quel format
(*/*;q=0.8). Ainsi, si un serveur dispose d’une représentation HTML,
XML et PDF pour une ressource, il doit retourner à ce client le format
HTML. Notez que cette valeur de l’en-tête Accept
est celle par
défaut du navigateur Firefox.
La négociation de jeu de caractères¶
Le client peut négocier avec le serveur le jeu de caractères (charset) utilisé dans la réponse grâce à l’en-tête Accept-Charset :
Négociation de contenu sur l’encodage
GET /individu/00001 HTTP/1.1
Host: www.monserveur.fr
Accept-Charset: iso-8859-1, utf-8;q=0.8, *;q=0.3
Si le serveur ne peut pas fournir de représentation utilisant un des jeux caractères spécifiés par l’en-tête Accept-Charset, il doit considérer que sa représentation n’est pas acceptable par le client. Dans ce cas, le serveur peut :
- Répondre par un code statut 406 (Not Acceptable)
- Ignorer l’en-tête et retourner une représentation utilisant le code caractères de son choix. En effet, on considère que la décision de traiter ou non la réponse revient en dernier lieu au client.
La négociation de langue¶
Si la réponse contient des données textuelles destinées à être lues par des individus, le client peut négocier la langue qui devrait être utilisée grâce à l’en-tête Accept-Language. Si le serveur ne peut pas satisfaire les exigences du client, il est tout de même sensé retourner ce qu’il juge la meilleure réponse afin de ne pas empêcher l’utilisateur d’accéder à l’information.
Négociation de contenu sur la langue du document
GET /individu/00001 HTTP/1.1
Host: www.monserveur.fr
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
La valeur de l’en-tête Accept-Language
de l’exemple ci-dessus est
celle du navigateur Firefox pour un utilisateur français. On peut le
traduire de la façon suivante : le client préfère les documents écrits
en langue française (fr). Sinon, le client préfère les documents
français (fr-fr;q=0.8). Sinon, le client préfère les documents écrits en
américain (en-us;q=0.5). Sinon le client préfère les document écrits en
langue anglaise (en;q=0.3).
La négociation de contenu proactive pour la langue est une technique utilisée pour internationaliser un site Web.
L’en-tête Vary¶
L’en-tête Vary est très utile pour donner au client un indice sur le type de négociation de contenu proactive qu’il peut réaliser. En effet, lorsqu’un serveur dispose de plus d’une représentation et qu’il répond à un client, il peut ajouter l’en-tête Vary qui indique la liste des en-têtes pouvant l’influencer dans son processus de sélection et de représentation de la réponse.
Exemple de découverte d’une négociation de contenu proactive
HEAD /individu/00001 HTTP/1.1
Host: www.monserveur.fr
HTTP/1.1 200 OK
Host: www.monserveur.fr
Vary: Accept, Accept-Language
Content-type: text/plain;charset=utf-8
Content-Language: en-us
Content-length: 532
Dans l’exemple ci-dessus, le client peut savoir grâce à une requête
HEAD
que le serveur retourne par défaut une représentation texte
brut en UTF-8 rédigée en américain. De plus, l’en-tête
Vary indique
que le serveur accepte la négociation de contenu proactive sur le type
de la représentation (Accept
) et sur la langue
(Accept-Language
).
Exercice¶
négociation de contenu proactive
Utilisez l’API Web du site http://rest-bookmarks.herokuapp.com pour
expérimenter la négociation de contenu proactive. À partir d’un bookmark
que vous aurez créé avec cette API, essayez de réaliser une négociation
de contenu sur le type de représentation (avec l’en-tête Accept
).
Trouvez des cas pour lesquels :
- vous obtenez un format de représentation différent de celui par défaut
- vous obtenez une réponse 406 de la part du serveur
Écrivez la liste des commandes cURL pour réaliser les actions ci-dessus.