Affichage des articles dont le libellé est Apache. Afficher tous les articles
Affichage des articles dont le libellé est Apache. Afficher tous les articles

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.

vendredi 24 septembre 2010

Coloration syntaxique Apache 1.3 dans Notepad++

Notepad++ est un éditeur de texte libre et gratuit très léger et performant : il s'ouvre quasiment instantanément même sur des machines modestes et fournit de nombreuses fonctionnalités comme la gestion des onglets, la réouverture automatique des fichiers, l'affichage simultané de deux fenêtres de texte, les macros, la coloration syntaxique pour de nombreux langages, la surveillance de la modification des fichiers ouvert dans Notepad++ par d'autre logiciels, une implémentation shell permettant d'ouvrir n'importe quel fichier à partir du menu contextuel (click droit) de l'explorateur, la possibilité de faire des rechercher/remplacer dans des répertoire complet et toute leur arborescence, avec ou sans regex, avec ou sans mode étendu (\n, \r , etc.)...

Bref, un outil indispensable à tout informaticien, car même ceux qui, comme moi affectionnent le confort de lourds IDE tel que Netbean ou Visual Studio, il est toujours intéressant d'avoir une alternative à un logiciel qui vous fera patienter 30 seconde lors de son lancement pour faire une modification qui en prendra 2.

Voici comment obtenir une coloration syntaxique pour les fichiers de configuration Apache 1.3 qui n'est pas nativement implémenté dans Notepad++ 5.6.8.

Bien qu'optimisé pour Apache 1.3, cette coloration syntaxique rend aussi plus confortable les fichiers de configurations d'Apache 2

Pour commencer :

Dans Notpad++ :

  • Ouvrir le panneau "Langage utilisateur",
  • cliquer sur le bouton "Nouveau..." et remplir "httpd.conf 1.3" dans le champ "Name :" de la fenêtre "Create New Language..." puis appuyer sur le bouton "OK",
  • s'assurer que la liste déroulante "Langage" est bien sur "httpd.conf 1.3".

Astuce : En ce qui concerne la police, il faut toujours mettre une police à pas fixe pour le code. Par défaut, la police "Fixedsys" est utilisé ici.

Info : Pour les commentaires, la police "Verdana" à été choisie pour faciliter la lisibilité.

Dans l'onglet "Bloc & défaut"

Dans "Style par défaut", choisir un gris foncé comme couleur de premier plan et la police "Fixedsys" dans "Famille".

Dans "Définition de bloc ouvrant" et "Définition de bloc fermant" choisir du bleu comme couleur de premier plans et la police "Fixedsys" dans "Famille"

Remplir le champ texte de "Définition de bloc ouvrant" avec :

<Limit <LimitExcept <Location <LocationMatch <VirtualHost <IfDefine <IfModule <Files <FilesMatch <Directory <DirectoryMatch <location

Remplir le champ texte de "Définition de bloc fermant" avec :

</Limit </LimitExcept </Location </LocationMatch </VirtualHost </IfDefine </IfModule </Files </FilesMatch </Directory </DirectoryMatch </location

Dans l'onglet "Mots clés"

"1er Groupe" :

  • Couleur de premier plan bleu foncé,
  • police "Fixedsys" dans "Famille",
  • cocher "Souligné",

Remplir le champ texte avec :

AcceptFilter AcceptMutex AccessConfig AccessFileName Action AddAlt AddAltByEncoding AddAltByType AddCharset AddDefaultCharset AddDescription AddEncoding AddHandler AddIcon AddIconByEncoding AddIconByType AddLanguage AddModule AddModuleInfo AddType AgentLog Alias AliasMatch AllowCONNECT AllowOverride Anonymous Anonymous_Authoritative Anonymous_LogEmail Anonymous_MustGiveEmail Anonymous_NoUserID Anonymous_VerifyEmail AuthAuthoritative AuthDBAuthoritative AuthDBGroupFile AuthDBMAuthoritative AuthDBMGroupFile AuthDBMGroupFile AuthDBUserFile AuthDBMUserFile AuthDigestFile AuthGroupFile AuthName AuthType AuthUserFile BindAddress BrowserMatch BrowserMatchNoCase BS2000Account CacheDefaultExpire CacheDirLength CacheDirLevels CacheForceCompletion CacheGcInterval CacheLastModifiedFactor CacheMaxExpire CacheRoot CacheSize CheckSpelling ClearModuleList ContentDigest CookieExpires CookieTracking CoreDumpDirectory CustomLog DefaultIcon DefaultLanguage DefaultType DirectoryIndex DocumentRoot EBCDICConvert EBCDICConvertByType EBCDICKludge ErrorDocument ErrorLog Example ExpiresActive ExpiresByType ExpiresDefault ExtendedStatus FancyIndexing ForceType ForensicLog Group Header HeaderName HostNameLookups IdentityCheck ImapBase ImapDefault ImapMenu Include IndexIgnore IndexOptions IndexOrderDefault ISAPIReadAheadBuffer ISAPILogNotSupported ISAPIAppendLogToErrors ISAPIAppendLogToQuery KeepAlive KeepAliveTimeout LanguagePriority LimitRequestBody LimitRequestFields LimitRequestFieldsize LimitRequestLine Listen ListenBacklog LoadFile LoadModule LockFile LogFormat LogLevel MaxClients MaxKeepAliveRequests MaxRequestsPerChild MaxSpareServers MetaDir MetaFiles MetaSuffix MimeMagicFile MinSpareServers MMapFile NameVirtualHost NoCache Options order PassEnv PidFile Port ProxyBlock ProxyDomain ProxyPass ProxyPassReverse ProxyReceiveBufferSize ProxyRemote ProxyRequests ProxyVia ReadmeName Redirect RedirectMatch RedirectPermanent RedirectTemp RefererIgnore RefererLog RemoveEncoding RemoveHandler RemoveType require ResourceConfig RewriteBase RewriteCond RewriteEngine RewriteLock RewriteLog RewriteLogLevel RewriteMap RewriteOptions RewriteRule RLimitCPU RLimitMEM RLimitNPROC Satisfy ScoreBoardFile Script ScriptAlias ScriptAliasMatch ScriptInterpreterSource ScriptLog ScriptLogBuffer ScriptLogLength SendBufferSize ServerAdmin ServerAlias ServerName ServerPath ServerRoot ServerSignature ServerTokens ServerType SetEnv SetEnvIf SetEnvIfNoCase SetHandler StartServers ThreadsPerChild TimeOut TransferLog TypesConfig UnsetEnv UseCanonicalName User UserDir VirtualDocumentRoot VirtualDocumentRootIP VirtualScriptAlias VirtualScriptAliasIP XBitHack Timeout Allow Deny Order HostnameLookups MIMEMagicFile CookieLog SSLEngine SSLCertificateFile SSLCertificateKeyFile SSLLog SSLLogLevel SSLRandomSeed SSLMutex SSLSessionCacheTimeout SSLSessionCache SSLPassPhraseDialog

"2è Groupe" :

  • Couleur de premier plan bleu-vert,
  • police "Fixedsys" dans "Famille".

Remplir le champ texte avec :

CacheNegotiatedDocs SSLRequireSSL

"3è Groupe" :

  • Couleur de premier plan bleu clair,
  • police "Fixedsys" dans "Famille".

Remplir le champ texte avec :

Off On None on off none error warn info trace debug builtin deny,allow allow,deny Mutual-failure all valid-user Basic All Indexes Includes FollowSymLinks ExecCGI MultiViews

"4è Groupe" :

  • Couleur de premier plan bleu-vert foncé,
  • police "Fixedsys" dans "Famille",
  • cocher "Souligné",

Remplir le champ texte avec :

from user group startup connect

Dans l'onglet "Commentaire & Nombre" :

"Commentaire sur une ligne" :

  • Couleur de premier plan vert,
  • police "Verdana" dans "Famille",
  • cocher "Traiter comme un symbole",
  • remplir le champ texte avec le caractère : "#" (dièse).

"Nombre" :

  • Couleur de premier plan rouge.

Dans l'onglet "Opérateurs" :

  • Passer le caractère ">" de la liste des "Symboles disponibles" à la liste des "Opérateurs activés",
  • prendre le même bleu que pour les blocs en couleur de premier plan,
  • police "Fixedsys" dans "Famille",
  • cocher "Enable escape character :" et rentrer le caractère : "\" (back-slash).

"Délimiteur 1" :

  • "Borne ouvrante :" : """ (double guillemet),
  • "Borne fermante :" : """ (double guillemet),
  • Couleur de premier plan mauve,
  • police "Fixedsys" dans "Famille".

Ressources :

Nomenclature

Voici le contexte dans lequel à été testé la réalisation des étapes ci-dessus :

  • Ordinateur (Asus EeePc 1000H) 
    • Intel Atom 1,6 GHz,
    • 2 Gio RAM,
    • Windows Vista 32 bits.
  • Logiciel utilisé 
    • Notepad++ 5.6.8 version française.
  • Fichier de test utilisé 
    • "httpd.conf" par défaut de la version Apache 1.3 implémenté dans OpenBSD 4.5.

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 droits.

Tout autre contenu ou ressource est soumis à l'acceptation du contrat Creative Commons by-nc-nd.

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.