next up previous contents Next: Installation et configuration d'Apache. Up: httpd: serveur web Apache. Previous: httpd: serveur web Apache.   Table des matières  


37.1 Bases à propos des serveurs web.

Dans la section 27.2, nous avons vu un exemple de session HTTP au cours de laquelle nous avons utilisé la commande telnet. En réalité, un serveur web n'est rien d'autre qu'un programme qui lit un fichier situé sur le disque dur chaque fois qu'un requête GET /<nom_de_fichier>.html HTTP/1.0 arrive sur le port 80. Dans cette section, nous montrons un cas de serveur web écrit avec un script de shell [ce programme provient d'un auteur qui n'a pas signé le code source; aussi, si vous vous reconnaissez, n'hésitez pas à envoyer un mél]. Vous devrez ajouter la ligne suivante:

www stream  tcp  nowait  nobody  /usr/local/sbin/sh-httpd 


dans votre fichier /etc/inetd.conf. Si vous exécutez xinetd, vous devrez plutôt ajouter un fichier contenant:

service www 
{ 
     socket_type       = stream 
     wait              = no 
     user              = nobody 
     server            = /usr/local/sbin/sh-httpd 
} 


dans votre répertoire /etc/xinetd.d/. Ensuite, vous pourrez arrêter tous les serveurs web déjà en cours et redémarrer inetd (ou xinetd). Vous devrez également créer un fichier de journalisation (/usr/local/var/log/sh-httpd.log) et au moins une page web (/usr/local/var/sh-www/index.html) que votre serveur acheminera. Elle pourrait contenir ceci, par exemple:

<HTML> 
 <HEAD> 
  <TITLE>Mon premier document</TITLE> 
 </HEAD> 
 <BODY bgcolor=#CCCCCC text=''#000000''> 
Ceci est mon premier document<P> 
Visitez-le. 
  <A HREF=''http://rute.sourceforge.net/'' 
   The Rute Home Page 
  </A> 
pour plus d'information.</P> 
 </BODY> 
</HTML> 


Notez que le serveur fonctionne sous l'utilisateur nobody, si bien que le fichier de journalisation doit être en écriture pour cet utilisateur; le fichier index.html doit être en lecture. Notez également l'utilisation de la commande getpeername, qui peut être modifiée en PEER='''' si vous n'avez pas installé le paquet netpipes. [Il n'est possible que les autres commandes utilisées soient disponibles sur d'autres systèmes UNIX].

#!/bin/sh 
VERSION=0.1 
NAME=''ShellHTTPD'' 
DEFCONTENT=''text/html'' 
DOCROOT=/usr/local/var/sh-www 
DEFINDEX=index.html 
LOGFILE=/usr/local/var/log/sh-httpd.log 
 
log() { 
   local REMOTE_HOST=$1 
   local REFERRER=$2 
   local CODE=$3 
   local SIZE=$4 
 
   echo ``$REMOTE_HOST $REFERRER - [$REQ_DATE] \ 
\''${REQUEST}\'' ${CODE} ${SIZE}'' » ${LOGFILE} 
} 
 
print_header() { 
   echo -e ``HTTP/1.0 200 OK\r'' 
   echo -e ``Server: ${NAME}/${VERSION}\r'' 
   echo -e ``Date: `date`\r'' 
} 
 
print_error() { 
   echo -e ``HTTP/1.0 $1 $2\r'' 
   echo -e ``Content-type: $DEFCONTENT\r'' 
   echo -e ``Connection: close\r''

   echo -e ``Date: `date`\r'' 
   echo -e ``\r'' 
   echo -e ``$2\r'' 
   exit 1 
} 
 
guess_content_type() { 
   local FILE=$1 
   local CONTENT 
 
   case ${FILE##*.} in 
      html) CONTENT=$DEFCONTENT ;; 
      gz) CONTENT=application/x-gzip ;; 
      *) CONTENT=application/octet-stream ;; 
   esac 
 
   echo -e ``Content-type: $CONTENT'' 
} 
 
do_get() { 
   local DIR 
   local NURL 
   local LEN 
 
   if [ ! -d $DOCROOT ]; then 
      log ${PEER} - 404 0 
      print_error 404 ``No such file or directory'' 
   fi 
 
   if [ -z ``${RL##*/}'' ]; then 
      URL=${URL}${DEFINDEX} 
   fi 
 
   DIR=''`dirname $URL`'' 
   if [ ! -d ${DOCROOT}/${DIR} ]; then 
      log ${PEER} - 404 0 
      print_error 404 ``Directory not found'' 
   else 
      cd ${DOCROOT}/${DIR} 
      NURL=''`pwd`/`basename ${URL}`'' 
      URL=${NURL} 
   fi 
 
   if [ ! -f ${URL} ]; then 
      log ${PEER} - 404 0 
      print_error 404 ``Document not found'' 
   fi 
 
   print_header 
   guess_content_type ${URL} 
   LEN=''`ls -l ${URL} | tr -s ' ' | cut -d ' ' -f 5`'' 
   echo -e ``Content-length: $LEN\r\n\r'' 
   log ${PEER} - 200 ${LEN} 
   cat ${URL} 
   sleep 3 
} 
 
read_request() { 
   local DIRT 
   local COMMAND 
 
   read REQUEST 
   read DIRT 
 
   REQ_DATE=''`date +''%d/%b/%Y:%H:%M:%S %z''`'' 
   REQUEST=''echo ${REQUEST} | tr -s [:blank:]`'' 
   COMMAND=''`echo ${REQUEST} | cut -d ' ' -f 1`'' 
   URL=''`echo ${REQUEST} | cut -d' ' -f 2`'' 
   PROTOCOL=''`echo ${REQUEST} | cut -d ' ' -f 3`'' 
 
   case $COMMAND in 
      HEAD) 
          print_error 501 ``Not implemented (yet)'' 
          ;; 
      GET) 
          do_get 
          ;; 
      *) 
          print_error 501 ``Not implemented'' 
          ;; 
      esac 
} 
 
# 
# It was supposed to be clean - without any non-standard utilities  
# but I want some logging where the connexions come from, so 
# I use just this one utility to get the peer address 
# 
# This is from the netpipes package 
PEER=''`getpeername | cut -d ' ' -f 1`'' 
 
read_request 
 
exit0 



A présent, exécutez telnet localhost 80, comme dans la section 27.2. Si cela fonctionne, et que vos fichiers de journalisation se remplissent correctement (tail -f ...), vous pouvez essayer de vous connecter à http://localhost avec un navigateur web comme Firefox, Mozilla, Galeon, Netscape.

Notez encore que la commande getsockname (qui vous indique les adresses IP [parmi les vôtres] auxquelles un client distant se connecte) pourrait permettre au script de servir des pages web à partir d'un répertoire différent pour chaque adresse IP. Voici en bref en quoi consiste les domaines virtuels [...].


next up previous contents Next: Installation et configuration d'Apache. Up: httpd: serveur web Apache. Previous: httpd: serveur web Apache.   Table des matières  
1-01-2006