This is an old revision of the document!
De nombreuses plates-formes logicielles développées aujourd'hui sont basées sur des données reçues d'un serveur Web.
Un serveur Web est un programme qui s'exécute sur une ou plusieurs machines accessibles via Internet. En revanche, plusieurs clients peuvent faire des demandes à un serveur, qui répondra avec les informations demandées.
Afin de pouvoir communiquer entre le client et le serveur, les données modifiées doivent suivre des règles claires, appelées protocole. Dans le cas des serveurs Web, le protocole utilisé est HTTP.
HTTP (Hypertext Transfer Protocol) est un protocole utilisé à l'échelle mondiale, étant le protocole derrière le World Wide Web, ou ce que nous connaissons simplement comme «Web». La plupart des ressources Web partagées sur Internet sont transférées via HTTP.
Lorsque nous parlons d'applications Web, les expressions «serveur Web» et «client Web» sont fréquemment utilisées. Par conséquent, nous pouvons dire que HTTP convient à un type de communication client-serveur. Dans cette architecture, nous avons le serveur d'une part, en attente de réponse, et le client, d'autre part, demande des ressources (ou des données) au serveur. Le résultat est que les messages envoyés sont des paires requête-réponse.
Chaque paquet HTTP peut être divisé en trois composants principaux: la ligne de départ, l'en-tête et le corps du message. La ligne de départ contient des informations sur le message, l'en-tête du paquet contient des métadonnées, des informations sur les données réelles, tandis que le corps contient les informations réelles à transmettre. Bien que la structure générale soit la même pour les messages de demande et de réponse, les deux diffèrent légèrement lorsqu'ils sont analysés en détail.
Des messages de demande sont envoyés du client au serveur pour demander des informations (demander des ressources au serveur). Le format d'un message de demande est le suivant: {METHOD} {URL} {VERSION} {HEADERS} {BODY}.
Exemple de paquet de requête HTTP
POST / HTTP/1.1 Ocp-Apim-Subscription-Key: 414574517b91467ea8e565ea19720650 Content-Type: application/json cache-control: no-cache Postman-Token: 4fb8e75e-ba74-4cac-b9ec-8ee1a81f1e94 User-Agent: PostmanRuntime/7.1.1 Accept: */* Host: localhost:8000 accept-encoding: gzip, deflate content-length: 37 Connection: keep-alive {"name": "Harry Potter", "age": 10 }
Le message de réponse, envoyé du serveur au client, a le format générique suivant: {VERSION} {STATUS} {RAISON} {HEADERS} {BODY}.
Exemple de paquet HTTP reponse
HTTP/1.1 200 status: 200 content-type: text/html connection: close <html><button>response</button></html>
Lorsque nous travaillons avec le protocole HTTP, qui a été spécialement conçu pour le Web, nous pouvons considérer qu'avec chaque demande que nous faisons au serveur, en principe, nous accédons à une ressource sur ce serveur, que ce soit de vrais fichiers ou des données uniquement. Pour chaque ressource à laquelle nous pouvons accéder, il existe un moyen d'y accéder. L'URL (Uniform Resource Locator) est une chaîne qui indique une ressource spécifique sur le Web (par exemple, http://www.wyliodrin.com/projects/app;user=lcss123?id=1234abcd).
Le schéma général d'une URL est le suivant: protocol:host:port/path;params?query#fragment
.
Tous les composants URL ne sont pas requis, dans la plupart des cas, nous n'utiliserons que le protocole, l'hôte et le chemin.
==== Méthodes HTTP ====
Comme nous l'avons déjà établi, HTTP fonctionne avec les messages de demande-réponse. Cela signifie que le client doit soumettre une demande pour obtenir une ressource, et cela se fait via l'URL. Cependant, nous pouvons faire différents types de demandes. C'est pourquoi une requête est définie par une méthode avec l'URL, afin que nous puissions avoir différentes requêtes en fonction de leur finalité (récupérer des données, modifier des données, supprimer des données, etc.). Certaines des méthodes HTTP les plus utilisées sont
GET et
POST.
<note>
Il est important de comprendre que les méthodes sont des conventions simples et leur utilisation dépend de la façon dont le serveur est implémenté. Pour chaque demande, quel que soit le type de méthode, le serveur doit émettre une réponse. Par conséquent, chaque serveur peut implémenter différentes méthodes.
</note>
==== En-tête de message HTTP ====
Comme mentionné précédemment, l'une des parties principales d'un message HTTP est l'en-tête. Il contient des informations importantes sur la demande ou la réponse.
Certaines informations sont génériques et peuvent être trouvées dans les messages de demande et les réponses, tandis que d'autres propriétés sont spécifiques à l'une d'entre elles. Par exemple, vous pouvez trouver la propriété
Date dans les deux messages et stocker la date et l'heure de génération du message. D'un autre côté, nous avons la propriété
Accept, qui est utilisée dans une demande pour spécifier au serveur à quel type de fichiers multimédias il doit répondre.
==== Codes d'état ====
Le code d'état d'une réponse informe le client du résultat de sa demande. Les codes d'état sont divisés en cinq catégories et, sur la base de ceux-ci, nous pouvons déduire le résultat de la demande envoyée. Les codes les plus importants sont:
- 200 - 299 - Codes de réussite - les demandes ont été acceptées;
- 400 - 499 - Codes d'erreur client - la demande ne peut pas être traitée par le serveur, elle n'est pas conforme à ce que le serveur peut traiter;
- 500 - 599 - Codes d'erreur du serveur - la demande ne peut pas être traitée car le serveur ne fonctionne pas correctement.
==== Corps du message HTTP ====
Le corps d'un message HTTP représente les données brutes à transmettre. Étant donné que toutes les demandes ou réponses ne nécessitent pas de transmission de données, le corps est facultatif dans un message.
Les données peuvent être structurées dans différents formats (par exemple, structure JSON, structure XML, texte). C'est pourquoi lors de l'envoi des données, nous ajoutons l'en-tête Content au message, afin de préciser la structure des données.
Actuellement, la plupart des services Web HTTP fonctionnent avec des structures JSON.
<note>
Plus de détails sur les messages HTTP sont disponibles sur le lien suivant: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages.
</note>
===== JSON =====
Le moyen le plus utilisé pour représenter les données est le JSON.
La notation d'objet JavaScript (JSON) est une syntaxe utilisée pour stocker et transmettre des données. Ce format a été développé pour être facile à analyser et à générer, tout en étant facile à comprendre par les humains.
Le format JSON est basé sur deux structures:
Une collection de paires clé-valeur, semblable à un dictionnaire;
Une liste de valeurs.
<code json>
my_json = {“first_name”: “Harry”,
“last_name”: “Potter”,
“age”: 10,
“hobbies” : [“reading”, “magic”]}
</code>
Pour extraire une valeur d'une variable JSON, spécifiez sa clé: my_json [“age”].
En Python, les éléments JSON peuvent être générés et manipulés à l'aide du module json. Il présente deux fonctions importantes: dumps et loads.
La fonction
dumps () transforme un objet Python en une chaîne JSON.
<code python>
import json
# a Python object (dict):
x = {
“name”: “John”,
“age”: 30,
“city”: “New York”
}
# convert into JSON:
y = json.dumps(x)
# the result is a JSON string:
print(y)
</code>
La fonction
loads() transforme une chaîne JSON en un objet Python.
<code python>
import json
# some JSON:
x = '{ “name”:“John”, “age”:30, “city”:“New York”}'
# parse x:
y = json.loads(x)
# the result is a Python dictionary:
print(y[“age”])
</code>
===== Exercices =====
Le but de ce laboratoire est de créer un serveur Web minimal à partir du squelette de code ci-dessous.
<code python>
import socket
buffersize = 3072
s = socket.socket (family=socket.AF_INET, type=socket.SOCK_STREAM)
s.bind 1)
s.listen (0)
while True:
conn, addr = s.accept ()
data = conn.recv(buffersize)
msg = data.decode(“utf-8”)
print ('received')
print (msg)
conn.send 2)
conn.send 3)
conn.close()
</code>
Dans cet exemple, nous avons créé un serveur TCP qui reçoit des données d'un client, les affiche, puis répond avec le message:
<code>
HTTP/1.0 200 OK - protocolul HTTP versiunea 1.0, cod de eroare 200 OK
Connection: close - inchidem conexiunea dupa trimiterea raspunsului catre client
response
</code>
Dans ce message, les deux premières lignes font partie de l'en-tête et la dernière ligne est le corps du message.
<note>
Les messages HTTP envoyés depuis le serveur ou le client auront le format suivant:
<code>
linie antet
linie antet
…
linie antet
mesaj
</code>
</note>
===== Exercice 1 - GET message =====
- Exécutez l'exemple ci-dessus et accédez à l'adresse
localhost:8000 dans votre navigateur. Notez la réponse reçue dans le navigateur et inspectez le message reçu par le serveur.
- Accédez à l'adresse de l'hôte
localhost:8000/hello/world.
===== Exercice 2 - HTML response =====
Modifiez le serveur précédent pour qu'il réponde avec une page html. Le message envoyé par le serveur devrait ressembler à ceci:
<code>
HTTP/1.0 200 OK
Content-type: text/html
Connection: close
<html>…</html>
</code>
===== Exercice 3 - POST message =====
Téléchargez l'application postman et utilisez-la pour envoyer un message POST au serveur (dans la section Corps, sélectionnez raw, text). Envoyez un court message dans le corps du message à l'aide de Postman et inspectez l'intégralité du message reçu par le serveur.
===== Exercice 4 - POST response =====
Modifiez le serveur afin qu'il lit le corps du message reçu et envoie une réponse différente en conséquence, de la maniere suivante:
- répondre au message
age avec un numéro;
- répondre au message
name avec un nom;
- répondre au message
country avec un pays.
===== Exercice 5 - JSON response =====
Ajoutez au serveur l'option qu'à une requête GET, sur la route
localhost:8000/person il répond avec JSON similaire a:
<code json>
{
“name” : “Harry Potter”,
“age” : 10,
“country” : “UK”
}
</code>
===== Exercice 6 - Form server =====
Créez un serveur Web qui stockera les données des personnes, reçues des clients et qui répondront avec ces informations. Le comportement du serveur est le suivant:
- lors d'une requête
POST à l'adresse
localhost:8000/insert reçoit dans le corps un JSON comme celui ci-dessous et renvoie le code 200 si les données ont été enregistrées ou 500, si quelque chose n'a pas fonctionné.
<code json>
{
“name” : “Harry Potter”,
“age” : 10,
“country” : “UK”
}
</code>
- lors d'une demande
GET à l'adresse
localhost:8000'' renvoie un JSON avec toutes les données stockées, sous la forme suivante:
<code json>
[{
“age” : int_value1,
“name” : “nume_persoana1”,
“country” : “tara persoana1”
},
{
“age” : int_value2,
“name” : “nume_persoana2”,
“country” : “tara persoana2”
},….]
</code>
===== Exercice 7 - Form client =====
Créez un client Python pour envoyer des messages au serveur au lieu de Postman. Dans ce cas, vous pouvez simplifier le message afin que l'en-tête ne contienne que les informations nécessaires au traitement du package.
===== Bonus =====
Modifiez le programme créé précédemment pour qu'il réponde avec une page Web qui contient 3 entrées et envoie ces données en appuyant sur un bouton, après quoi il affichera les informations reçues.