Skip to content
Snippets Groups Projects
Commit 064fd848 authored by James R. Wilcox's avatar James R. Wilcox
Browse files

ch8 live code

parent eef3655d
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@ import tkinter.font
import socket
import ssl
import sys
import urllib.parse
from typing import Dict, List, Literal, Optional, Union
......@@ -112,7 +113,36 @@ class Tab:
self.focus = elt
elt.attributes["value"] = ""
return self.render()
elt = elt.parent
elif elt.tag == "button":
# elt is the button we clicked
while elt:
if elt.tag == "form" and "action" in elt.attributes:
self.submit_form(elt)
elt = elt.parent
if elt is not None:
elt = elt.parent
# elt is the node of the <form> tag
def submit_form(self, elt):
# find all <input> tags that are descendents of elt
inputs = [node for node in tree_to_list(elt, [])
if isinstance(node, Element)
and node.tag == "input"
and "name" in node.attributes]
# form encode the key-value pairs
body = ""
for input in inputs:
name = input.attributes["name"]
value = input.attributes.get("value", "")
name = urllib.parse.quote(name)
value = urllib.parse.quote(value)
body += "&" + name + "=" + value
body = body[1:]
url = elt.attributes["action"]
url = resolve_url(url, self.url)
headers, body = request(url, body)
def scrolldown(self):
max_y = max(self.document.height - (HEIGHT - CHROME_PX), 0)
......@@ -275,8 +305,9 @@ class Browser:
self.tabs.append(new_tab)
self.draw()
def request(url):
# if payload == None, then send a GET request
# otherwise, send a POST request with the payload as the body
def request(url, payload=None):
scheme, url = url.split("://", 1)
assert scheme in ["http", "https"], f"Unknown scheme: {scheme}"
......@@ -301,8 +332,18 @@ def request(url):
s.connect((host, port))
s.send(bytes(f"GET {path} HTTP/1.0\r\n", encoding="utf8") +
bytes(f"Host: {host}\r\n\r\n", encoding="utf8"))
method = "POST" if payload is not None else "GET"
body = (f"{method} {path} HTTP/1.0\r\n" +
f"Host: {host}\r\n")
if payload is not None:
length = len(payload.encode("utf8"))
body += f"Content-Length: {length}\r\n"
body += "\r\n" + (payload or "")
s.send(body.encode("utf8"))
response = s.makefile("r", encoding="utf8", newline="\r\n")
statusline = response.readline()
......
import socket
counter = 0
def do_request(method, url, headers, body):
print(method, url, headers, body)
global counter
counter += 1
return "200 OK", f"<html>hello you are the lucky {counter}th visitor</html>"
def handle_connection(conx):
req = conx.makefile("b")
reqline = req.readline().decode("utf8")
method, url, version = reqline.split(" ", 2)
assert method in ["GET", "POST"]
headers = {}
for line in req:
line = line.decode('utf8')
if line == '\r\n': break
header, value = line.split(":", 1)
headers[header.lower()] = value.strip()
print(method, url, version, headers)
if 'content-length' in headers:
length = int(headers['content-length'])
body = req.read(length).decode('utf8')
else:
body = None
status, body = do_request(method, url, headers, body)
response = "HTTP/1.0 {}\r\n".format(status)
response += "Content-Length: {}\r\n".format(
len(body.encode("utf8")))
response += "\r\n" + body
conx.send(response.encode('utf8'))
conx.close()
if __name__ == "__main__":
s = socket.socket(
family=socket.AF_INET,
type=socket.SOCK_STREAM,
proto=socket.IPPROTO_TCP,
)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 8000))
s.listen()
while True:
conx, addr = s.accept()
handle_connection(conx)
<html>
<body>
<form action="/submit" method="post">
<p>Name: <input name=name value=1></p>
<p>Comment: <input name=comment value=2></p>
<p><button>Submit!</button></p>
<p>Name: <input name=name value=1></p>
<p>Comment: <input name=comment value=2></p>
<p><button>Submit!</button></p>
</form>
</body>
</html>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment