Explorar o código

Mini serveur et controleurs

Benoît Hubert %!s(int64=7) %!d(string=hai) anos
pai
achega
5e3a810138

+ 52 - 0
exemples/5-mini-serveur-http/controleurs.py

@@ -0,0 +1,52 @@
+from urllib.parse import parse_qs
+
+home_html = """<h1>Home</h1>
+<h2>Registered Users</h2>
+<ul>
+{users}
+</ul>
+"""
+
+login_html = """<h1>Home</h1>
+<form action="/login" method="POST">
+  <input name="email" placeholder="email" /><br>
+  <input type="password" placeholder="password" name="pw" /><br>
+  <input type="submit" value="Submit" />
+</form>
+"""
+
+users = [
+    { 'name': 'Jon Snow', 'email': 'jonsnow@winterfell.com', 'pw': 'dany' },
+    { 'name': 'Arya Stark', 'email': 'arya@winterfell.com', 'pw': 'dagger' },
+    { 'name': 'Sansa Stark', 'email': 'sansa@winterfell.com', 'pw': 'killramsay' },
+    { 'name': 'Bran Stark', 'email': 'bran@winterfell.com', 'pw': 'raven' }
+]
+
+def make_user_list_item(user):
+    return '<li><a href="mailto:' + user['email'] + '">' + user['name'] + '</a></li>'
+
+class HomeController:
+    def do_GET(self):
+       items = [make_user_list_item(user) for user in users]
+       items_joined = "\n".join(items)
+       return home_html.replace("{users}", items_joined)
+
+class LoginController:
+    def do_GET(self):
+       return login_html
+
+    def do_POST(self, raw_body):
+        body = parse_qs(raw_body)
+        print("LoginController.do_POST body", raw_body, body)
+        matching_users = [user for user in users if user['email'] == body['email'][0] and user['pw'] == body['pw'][0]]
+        # # print(matching_users)
+        # for u in users:
+        #     if(u['email'] == body['email'][0] and u['pw'] == body['pw'][0]):
+        #         return "<ul>" + make_user_list_item(matching_users[0]) + "</ul>"
+        #     else:
+        #         print("no match", u['email'], u['pw'], body['email'], body['pw'])
+        return "<ul>" + make_user_list_item(matching_users[0]) + "</ul>" if matching_users else "bad credentials"
+
+class RegisterController:
+    def do_GET(self):
+       print('I am RegisterController')

+ 81 - 4
exemples/5-mini-serveur-http/mini-serveur.py

@@ -1,11 +1,27 @@
 from http.server import BaseHTTPRequestHandler, HTTPServer
+import importlib
+# module = importlib.import_module('controlers')
+import controleurs
 
 base_html = """<!DOCTYPE html>
 <html>
   <head>
     <title>Mini-Serveur</title>
+    <style>
+      input {
+        padding: 4px 12px;
+        border: 1px solid #ddd;
+        border-radius: 4px;
+        margin-bottom: 10px;
+      }
+    </style>
   </head>
   <body>
+    <nav>
+      <a href="/">Home</a> |
+      <a href="/login">Login</a> |
+      <a href="/register">Register</a>
+    </nav>
     {body}
   </body>
 </html>
@@ -14,16 +30,25 @@ base_html = """<!DOCTYPE html>
 # HTTPRequestHandler class
 class MiniHTTPServerRequestHandler(BaseHTTPRequestHandler):
 
-  paths_GET = ["/", "/login", "/register"]
+  paths = {
+    "/": "HomeController",
+    "/login": "LoginController",
+    "/register": "RegisterController"
+  }
 
   # GET
   def do_GET(self):
-        print(self.path)
-        if not self.path in self.paths_GET:
+        if not self.path in self.paths.keys():
             self.send_response(404)
             self.end_headers()
             return
 
+        controller_class = self.paths[self.path]
+        print(controller_class)
+        class_ = getattr(controleurs, controller_class)
+        instance = class_()
+        html = instance.do_GET()
+
         # Send response status code
         self.send_response(200)
 
@@ -32,7 +57,59 @@ class MiniHTTPServerRequestHandler(BaseHTTPRequestHandler):
         self.end_headers()
 
         # Send message back to client
-        message = base_html.replace("{body}", "Hello world!")
+        message = base_html.replace("{body}", html)
+
+        # Write content as utf-8 data
+        self.wfile.write(bytes(message, "utf8"))
+        return
+
+  # POST: copier-coller en grande partie de do_GET:
+  #   - on a ajouté deux lignes au début
+  #   - on renvoie au client ce qu'il nous a envoyé (message = post_body)
+  def do_POST(self):
+
+        if not self.path in self.paths.keys():
+            self.send_response(404)
+            self.end_headers()
+            return
+
+        # Cette ligne récupère le(s) header(s) content-length
+        # Même s'il n'y en a qu'un, get_all() renvoie une liste d'un élément
+        content_len_headers = self.headers.get_all('content-length')
+
+        # Si cette liste est vide, on ne peut pas continuer, car on ne sait pas combien
+        # d'octets on doit lire : on renvoie une réponse avec code 400 (Bad Request)
+        if not content_len_headers:
+            self.send_response(400)
+            self.end_headers()
+            return
+
+        # On convertit en entier la valeur string contenue dans le header content-type
+        content_len = int(content_len_headers[0])
+        # On lit ce nombre d'octets dans la requête
+        post_body = self.rfile.read(content_len)
+        # On convertit en chaîne le body
+        body_str = str(post_body, 'utf-8')
+
+
+
+        controller_class = self.paths[self.path]
+        print(controller_class)
+        class_ = getattr(controleurs, controller_class)
+        instance = class_()
+        html = instance.do_POST(body_str)
+
+
+
+        # Send response status code
+        self.send_response(200)
+
+        # Send headers
+        self.send_header('Content-type','text/html')
+        self.end_headers()
+
+        # On renvoie cela tel quel au client
+        message = base_html.replace("{body}", html)
 
         # Write content as utf-8 data
         self.wfile.write(bytes(message, "utf8"))