jeudi 7 octobre 2010

HTTP Status Codes

Les codes de retour HTTP sont des indications très précieuses envoyées par le serveur pour informer sur la manière dont la requête a été traitée.

Par exemple, si un navigateur web demande à un serveur HTTP de lui fournir le fichier "http://le.serveur.invalid/index.html" :

  • si le fichier existe et que l'utilisateur a le droit d'accéder à cette ressource, le serveur renverra le fichier au navigateur web avec le code retour "200: OK" (Requête traitée avec succès),
  • si l'utilisateur n'a pas le droit d'effectuer cette requête, le serveur renverra un code "401: Unauthorized" (Une autorisation est nécessaire pour accéder à la ressource). Pour ce qui est du fichier, soit une page préconfigurée au niveau du serveur sera renvoyée, soit rien du tout, laissant alors le logiciel ayant émis la requête (comme un navigateur web) informe l'utilisateur du problème,
  • si la requête de l'utilisateur est légitime et que le fichier n'existe pas, un code "404: Not Found" (Ressource non trouvé) sera renvoyé, avec le même processus pour le fichier que décrit dans le point précédant.

Et tout ceci ne sont que des exemples car il existe plusieurs dizaine de codes de retour HTTP.

Attention : Le comportement que je décris ci-dessus n'est pas forcément le comportement par défaut de tous les serveurs web :

En effet, dans certains cas, le serveur commence par vérifier si le fichier existe ou non, et renvoie un code "404: Not Found" s'il n'existe pas, avant même se soucier si l'utilisateur a le droit d'effectuer la requête.

C'est à mon sens un comportement qu'il faut corriger systématiquement lors de la mise en place d'un serveur web : Pourquoi un utilisateur serait-il informé de l'existence d'une ressource qu'il n'a même pas le droit de requérir ?

Astuce : Tout ces codes de retour sont à deux chiffres, préfixés d'un troisième informant sur la nature du retour. Il y a cinq préfixes de retour, ce qui permet de savoir rapidement à quel type de retour on a à faire, même si on ne connait pas le code en particulier :

  • 1xx : Information
  • 2xx : Succès
  • 3xx : Redirection
  • 4xx : Erreur du client
  • 5xx : Erreur du serveur

A la base cette information est destinée surtout aux applicatifs qui effectuent les requêtes, et non aux utilisateurs qui les utilisent.

Il est cependant aisé de les consulter :

  • En capturant le trafic :
  • En consultant ce que le navigateur reçoit :
    • à l'aide de l'onglet réseau du plugin Firebug de Firefox
    • à l'aide de l'onglet "Ressources" des "Outils de développement" de Google Chrome
    • ...
  • etc.

Maintenant, venons-en au cœur du problème qui me préoccupe :

De nombreux développeurs web ne se soucient pas du tout de ces codes retour, et ne vont pas hésiter à fournir une information à l'utilisateur, et une information contraire à l'applicatif !

Prenons le cas de Joomla! :

Si vous tentez de vous identifier sur la partie administrateur, et que votre paire identifiant/mot de passe est refusée, vous serez bien évidement gratifié d'un message du genre :

"L'identifiant et le mot de passe ne correspondent pas"

Malheureusement, si vous regardez le code retour, l'application ne se gène pas pour renvoyer un magnifique "200: OK" (Requête traitée avec succès) en lieu et place d'un nécessaire "401: Unauthorized" (Une autorisation est nécessaire pour accéder à la ressource) !

Pire, même si ce n'est pas le cas de Joomla!, dans le cas de ressources inexistantes (par exemple "index.php?id=4" alors qu'aucune ressource "id=4" n'existe) de nombreuses applications web n'hésitent pas à renvoyer un message du type "La page que vous recherchez n'existe pas" avec un code "200: OK" alors qu'un "404: Not Found" (Ressource non trouvé) serait bien plus indiqué !

D'accord, "index.php" existe, mais si "index.php?id=4" n'est pas capable de renvoyer une ressource, alors c'est qu'aucune ressource avec cette URI n'existe, le code de statut devrait donc être un "404: Not Found".

De la même manière, si "id" n'accepte que des entiers, "index.php?id=toto" se doit de retourner un code "400: Bad Request" (La syntaxe de la requête est erronée)...

De plus, ceci est extrêmement simple à mettre en place : tous les langages prévus pour négocier avec le protocole HTTP implémentent le nécessaire pour retourner les bons codes.

En PHP par exemple, c'est avec la fonction header que l'on peut effectuer cette opération :
  1. <?php
  2. header("Status: 404 Not Found");
  3. ?>

Pourquoi se soucierait-on de donner une information correcte au logiciel qui effectue la requête ?

Simplement parce que cette information peut servir :

J'ai vu des gens ajouter leurs pages d'erreur dans le "robot.txt" pour qu'elles ne soient plus référencées sur Google, alors qu'un code de retour signifiant une erreur aurait permis au robot de tout de suite comprendre qu'il n'y avait rien d'intéressant...

J'ai vu des gens chercher à parser avec JavaScript un message d'erreur textuel amoureusement forgé côté serveur pour vérifier si leur requête Ajax s'était correctement déroulée, alors qu'il leur aurait été tellement plus simple de renvoyer les codes de retour correspondant aux erreurs pour connaître la nature du problème et informer directement l'utilisateur pertinemment...

Et j'ai vu de nombreuses autres horreurs, mais dans tous les cas, la logique et l'intelligence, ne dictent-elles pas à elles seules de ne pas renvoyer un code retour de succès quand quelque chose a visiblement mal tourné ?

Droit d'auteur / propriété intellectuelle :

Cet article et son contenu sont régis par les conditions suivantes :

Tout contenu tiers est régi par les conditions des ayants droit.

Tout autre contenu ou ressource est soumis à l'acceptation du contrat Creative Commons by-nc-nd (Paternité - Pas d'Utilisation Commerciale - Pas de Modification).

En cas de non acceptation de tout ou partie des conditions (incluant celles des contenus tiers), le contenu de cet article reste la propriété morale et patrimoniale de son auteur, et tout usage non autorisé par écrit est explicitement proscrit.

Aucun commentaire:

Enregistrer un commentaire