Devoir 5 - Rustywebserver

Le but de ce devoir est de créer un serveur Web qui doit servir des fichiers et exécuter des scripts.

Informations générales

Date limite: Le 21 juin, 23h59
Note: 2 points de la note
Lien: Devoir 5

Connaissances évaluées

  • Compréhension du paradigme client-servur
  • Compréhension du protocole HTTP

Regles

  1. Le devoir doit contenir un fichier Readme.md ou vous allez expliquer votre solution (-0.1p)
  2. Un devoir qui est implémenté seulement pour passer les tests ne sera pas noté pour ces tests-la
  3. Les lectures et écritures (fichiers et socket) doivent être implémentées en utilisant async et await.

Tricher

Le devoir doit etre résolu individuellement. Toute tentative de tricher entraînera 0p pour ce devoir. Nous utiliserons également des systèmes de détection de trichage automatique. Si nous avons des doutes, nous vous poserons des questions supplémentaires concernant le devoir.

Questions

Si vous avez des questions concernant le devoir, posez-les en publiant un issue sur le github https://github.com/UPB-FILS-SdE2/questions avec le format [webserver] <le titre de votre question> . Vous aurez besoin d'un compte github pour publier des questions.

NE PUBLIEZ PAS DE CODE SOURCE. Cela est considéré comme copiage et vous aller recevoir 0p pour le devoir.

Si vous voulez recevoir un e-mail lorsque des problèmes sont signalés ou lorsqu'il y a de nouveaux messages, accédez au site github repository et cliquez sur Watch.

Server

Le serveur sera sera exécuté de la maniere suivante:

rustwebserver PORT ROOT_FOLDER

Pour résoudre le devoir, vous allez implémenter un serveur HTTP, qui peut traiter les demandes via des threads. Le serveur recevra des paquets HTTP des clients, effectuera diverses opérations et répondra avec des paquets HTTP (un format simplifié).

root_folder est un chemin absolu vers le répertoire racine, par rapport auquel toutes les requêtes seront effectuées. Par exemple, si une demande a le chemin /images/sunny.png et que le chemin racine est /home/server/root, le fichier avec le chemin absolu /home/server/root/images/sunny.png sera retourné.

Messages HTTP

Les messages HTTP reçus par le serveur auront le format générique suivant:

<request_type> <path> HTTP/1.1
<header_key>:<header_value>
...
<header_key>:<header_value>
 
<message>

Les messages HTTP envoyés par le serveur auront le format générique suivant:

HTTP/1.0 <status_code status> 
<header_key>:<header_value>
...
Connection: close
 
<message>

Les variables suivantes seront remplacées comme suit:

  • request_type - le type de demande (GET ou POST);
  • path- le chemin vers le fichier demandé (ex: / scripts / update);
  • header_key: header_value - paires de clés de valeur qui font partie de l'en-tête (ex: type de contenu: application / json);
  • message - le corps du message (la longueur du message est de 8 Ko maximum);
  • status_code status - le code d'état suivi de la description de l'état; nous définirons les valeurs possibles ci-dessous (par exemple 404 Not found).

Retour des fichiers

La première fonctionnalité du serveur est de renvoyer les fichiers demandés par les clients. Dans ce cas, le serveur recevra une demande GET vers un fichier et répondra avec le contenu du fichier.

Le serveur retournera seulement des fichiers qui se trouvent en root_folder ou ses sous-dossiers.

Demande HTTP

Dans ce cas, la demande recue par le serveur aura le format suivant:

GET <file_path_relative_to_root> HTTP/1.1
Host: localhost:8000
<other header lines>

La première ligne de l'application spécifie le chemin d'accès au fichier demandé. L'en-tête peut contenir d'autres lignes en plus de celles spécifiées ci-dessus.

Réponse HTTP

Pour répondre aux demandes de fichiers, le serveur renverra un message similaire a:

HTTP/1.1 <status_code status>
Content-type: <file_type>
Connection: close
 
<file_contents>

Selon la demande reçue et l'état du fichier demandé, l'état de la réponse peut être:

  • 200 OK - le fichier a été retourné;
  • 403 Forbidden - le serveur n'est pas autorisé à lire le fichier;
  • 404 Not Found - le fichier n'existe pas.

La troisième ligne de l'application spécifie le type de fichier renvoyé. Selon le type de fichier, file_type peut avoir les valeurs suivantes:

  • text / plain; charset = utf-8 - pour les fichiers texte (extension .txt);
  • text / html; charset = utf-8 - pour les fichiers html;
  • text / css; charset = utf-8 - pour les fichiers css;
  • text / javascript; charset = utf-8 - pour les fichiers js;
  • image / jpeg - pour les fichiers JPEG;
  • image / png - pour les fichiers PNG;
  • application / zip - pour les archives ZIP.
  • application / octet-stream - pour les fichiers avec ou sans autres extensions

Exécution d'un script

Certains des messages reçus des clients nécessiteront l'exécution de scripts. Ce type de demande est identifié par le chemin du fichier, et dans ce cas le chemin est un fichier du répertoire /scripts.

Tous les fichiers exécutables peuvent exister dans le répertoire /scripts. N'importe lequel de ces fichiers sera exécuté avec la commande ./script_name. Après l'exécution, le serveur répondra avec le résultat de l'exécution.

Le résultat de l'exécution correspond à ce que le script a écrit à l'écran (indice : utilisez un pipe)

Variables

Lorsque le script est exécuté, tous les en-têtes HTTP reçus du client sont envoyés en tant que variables d'environnement au script (astuce : utilisez execve).

Le script recevra deux variables d'environnement supplémentaires : Method et Path. Method a la valeur GET ou POST et Path a la valeur du chemin demandé.

Query String

Le moment de lire sur la définition de la query string.

Chaque variable de query string doit être envoyée au script en tant que variable d'environnement au format Query_title=value.

Demande HTTP

Dans ce cas, la demande recue par le serveur ressemblera a:

<request_type> <file_path_relative_to_root> HTTP/1.1
Host: localhost:8000
<other header lines>
 
<message - optional>

Dans ce cas, les requêtes (request_type) peuvent être de deux types: GET et POST.

Pour ces demandes, les lignes de l'en-tête, à l'exception des deux premières, sont transmises en tant que variables d'environnement pour le fichier à exécuter.

Si la demande est POST, il y aura également un corps de message. Ceci est transmis en entrée au script à exécuter.

Réponse HTTP

Dans ce cas, le serveur renverra un message sous la forme:

HTTP/1.1 <status_code status>
Connection: close
<other_headers>
 
<file_contents>

Le statut dans la réponse aura l'une des valeurs suivantes:

  • 200 OK - le traitement a été effectué avec succès et le résultat peut être trouvé dans le corps du message;
  • 403 Forbidden - le serveur n'est pas autorisé à lire ou exécuter le fichier;
  • 404 Not Found - l'exécutable requis n'existe pas;
  • 500 Internal Server Error - l'exécutable demandé n'a pas été exécuté avec succès; Dans ce cas, le texte du stderr sera ajouté au corps du message.

Le serveur doit s'assurer que les fichiers d'un répertoire autre que celui mentionné dans le ROOT_FOLDER ne peuvent pas être telecharge ou exécutés.

Log

Au démarrage, le serveur imprimera ce qui suit:

Root folder: <ansolute path to root folder>
Server listening on 0.0.0.0:PORT

Pour chaque requête, le serveur imprimera une ligne:

$Request request_source_ip_address $Path -> status_code (status_text)

Bonus

Mettre en œuvre la liste des dossiers pour le serveur Web. Si le chemin demandé est un dossier, générez une réponse html au format suivant.

<html>
  <h1>$Request</h1>
  <ul>
    <li><a href="/..">..</a></li>
    <li><a href="/file1">file1</a></li>
    <li><a href="/file2">file2</a></li>
    ...
  </ul>
</html>
sde2/teme/tema_fr_5_rust_2023.txt · Last modified: 2023/06/07 12:47 by alexandru.radovici
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0