Outils pour utilisateurs

Outils du site


nsi:tds:serveur_web20:requete

Module requete

Nom du fichier : requete.py

Défini une classe Requete chargée d’interpréter une requête d'un client reçue par le serveur.

Vous pouvez tester le bon fonctionnement avec le module de test : requete.test.py.

À quoi ressemblent les requêtes

Les requêtes sont toujours de simples textes qui peuvent avoir les formes suivantes :

Cas d'une requête GET

GET /dossier/sousdossier/test.html HTTP/1.1
Host: localhost:80
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

Dans ce cas l’URL demandée est /dossier/sousdossier/test.html

l’URL peut être plus compliquée. Rien n'empêche d'entrer une URL comme chose=45-id+74

Cas d'une requête POST avec des paramètres

POST /dossier/sousdossier/test.html HTTP/1.1
Host: localhost:80
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

x=17&monttexte=blablabla

C'est le cas où l'interface web contient un formulaire permettant à l'utilisateur d'envoyer des données. On utilise une requête POST seulement dans le cas où la requête est susceptible de modifier l'état du serveur (écrire dans la BDD) sinon on utilise une requête GET.

Il existe des requêtes PUT et DELETE mais elles sont moins connues et nous ne les utiliserons pas.

Interface de la classe Requete

  • méthode __init__(self, str_requete:str)str_requete est le texte de la requête
  • méthode url(self) -> str renvoie l’URL complète de la requête,
  • méthode is_GET(self) -> bool renvoie True si la méthode de la requête est GET,
  • méthode is_POST(self) -> bool renvoie True si la méthode de la requête est POST,
  • méthode post_params(self) -> dict renvoie les paramètres sous forme d'un dictionnaire en cas de requête POST. Précondition : requête POST.

Dans l'exemple ci-dessus, le retour serait {'x':'17', 'montexte':'blablabla'}

  • méthode match(self, pattern:str). Celle-ci est complexe, je détaille ci-dessous.

Méthode match

On veut pouvoir définir un schéma – pattern pour une URL générique.

Par exemple le schéma <nom>.html.

  • Si l’URL est dossier/monfichier.html, alors le schéma est vérifié et nom = 'dossier/monfichier'. La méthode devrait alors renvoyer {'nom':'dossier/monfichier'}
  • Si L’URL est image.jpg, alors le schéma n'est pas vérifié et la méthode devrait renvoyer False.

Autre exemple : le schéma /livre-<id>

  • Si l’URL est /livre-45, alors le schéma est vérifié et id = '45'. La méthode devrait alors renvoyer {'id':'45'}
  • Si l’URL est /blabla-18, alors le schéma n'est pas vérifié et la méthode devrait renvoyer False

Le schéma est donc constitué de parties fixes et de parties ente <...> variables qu'il faut récupérer.

Cette méthode nécessite l'utilisation d'expressions régulières. Je vous donne ci-dessous un peu d'aide :

# nécessite :
import re

# supposons que pattern = "/livre-<id>"
# et que url = "/livre-475"

regex_tag = "<[^<]*>" # consiste à chercher les <...>
for m in re.finditer(regexTag, pattern): # parcours les <...> trouvés dans pattern
    needle = m.group(0)       # ex: trouve "<id>"
    repl = "(?P"+needle+".*)" # ex: propose de remplacer par "(?P<id>.*)"
    pattern = re.sub(needle,repl,pattern) # effectue le remplacement
pattern = "^" + pattern + "$"
# l'expression est devenue : "^/livre-(?P<id>.*)$"
# on peut appliquer l'expression à l'url

retour = re.match(pattern, url)
# en cas d'échec, retour == None
# mais dans notre exemple, c'est un succès :
# "^/livre-(?P<id>.*)$" a bien reconnu "/livre-475" et a extrait id = 475
retour.groupdict()
# cette commande renvoie le résultat sous forme d'un dictionnaire :
# { 'id':'475' }
nsi/tds/serveur_web20/requete.txt · Dernière modification : de goupillwiki