Compare commits
2 Commits
30a9e0bedd
...
a4846211dc
Author | SHA1 | Date | |
---|---|---|---|
|
a4846211dc | ||
|
649a301cf9 |
33
http.py
33
http.py
@ -11,7 +11,7 @@ from io import StringIO
|
||||
from email.utils import formatdate
|
||||
|
||||
Fork = False
|
||||
# The next post in this series,which now has the name
|
||||
# The next post in this series, which now has the name
|
||||
# __The Network Programing Purgatorio__ by the way.
|
||||
# Was originally going to be about how to use TLS
|
||||
# But it turns out just kinda faking your http implementation
|
||||
@ -19,7 +19,7 @@ Fork = False
|
||||
# and security.
|
||||
|
||||
# Thus we have to devote some time and energy to making
|
||||
# a better fake http. We're still going to employ some
|
||||
# a more robust, but still fake http. We're still going to employ some
|
||||
# dirty tricks here.
|
||||
# At this point there if you didn't read Greg the Manokit's
|
||||
# Warning at the top of the page
|
||||
@ -38,6 +38,9 @@ Fork = False
|
||||
# client's code in a public project.
|
||||
# Thus cut 'n' paste.
|
||||
|
||||
CRLF = "\r\n"
|
||||
LF = "\n"
|
||||
|
||||
|
||||
class AccessDict(dict):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -83,6 +86,8 @@ class HttpRequest(AccessDict):
|
||||
self["headers"] = headers
|
||||
self["body"] = StringIO(body)
|
||||
self["path"] = path
|
||||
if "Host" not in self["headers"]:
|
||||
self["headers"]["Host"] = "localhost"
|
||||
|
||||
def read(self, seek):
|
||||
return self["body"].read(seek)
|
||||
@ -92,6 +97,7 @@ class HttpRequest(AccessDict):
|
||||
buf.write(f"{self.method} {self.path} HTTP/1.1")
|
||||
for k, v in self["headers"].items():
|
||||
buf.write(f"{k}: {v}\r\n")
|
||||
buf.write(CRLF + CRLF)
|
||||
buf.write(self["body"].getvalue() + "\r\n")
|
||||
return buf.getvalue() + "\r\n"
|
||||
|
||||
@ -115,14 +121,17 @@ class HttpResponse(AccessDict):
|
||||
def write(self, stuff):
|
||||
return self.body.write(stuff)
|
||||
|
||||
# Foreshadowing (n): A literary device in which an author ...
|
||||
def __str__(self):
|
||||
buf = StringIO()
|
||||
print(self.headers)
|
||||
buf.write(f"HTTP/1.1 {self.status}\r\n ")
|
||||
buf.write(f"HTTP/1.1 {self.status}\r\n")
|
||||
length = len(self["body"].getvalue())
|
||||
for k, v in self["headers"].items():
|
||||
buf.write(f"{k}: {v}\r\n")
|
||||
buf.write(f"Content-Length: {length}\r\n")
|
||||
buf.write(CRLF + CRLF) # Per RFC 9112
|
||||
|
||||
buf.write(self["body"].getvalue() + "\r\n")
|
||||
return buf.getvalue() + "\r\n"
|
||||
|
||||
@ -201,6 +210,17 @@ def server_handler():
|
||||
|
||||
|
||||
# I made two simple changes to make it use our new http objects
|
||||
# This will still accept anything as long as the method verb
|
||||
# is correct. Clients need not conform to RFC 9112 (yet).
|
||||
# We however, do our best effort to conform to rfc 9112,
|
||||
# when sending responses.
|
||||
#
|
||||
# The principal of being lienant in what you accept from
|
||||
# the client, but strict in what you send back, was first
|
||||
# was first forumlated by John Postel in that later half
|
||||
# of the 1970s.
|
||||
|
||||
# Doing this, is also motivation for me to write Parts 4, 5, and 6
|
||||
|
||||
|
||||
def client_handler(sock):
|
||||
@ -257,12 +277,15 @@ else:
|
||||
# To recap we just did a bunch of work, for no user visible change
|
||||
# This is not a bad thing, often the first drafts of programs.
|
||||
# Will fit the requirements of the moment. But when the requirements
|
||||
# change the program must be adapted to fit.abs
|
||||
# change the program must be adapted to fit.
|
||||
# This process of iteration and redesign,
|
||||
# is called "paying down technical debt", and it should be done whenever
|
||||
# possible.
|
||||
#
|
||||
# And we've just moved up to the second level of the 7 story mountain
|
||||
# Yay us.
|
||||
#
|
||||
# References
|
||||
# MDN Web Docs
|
||||
# Robustness Principal (Devopedia): https://devopedia.org/postel-s-law
|
||||
# IETF RFC 9112 HTTP/1.1 https://datatracker.ietf.org/doc/html/rfc9112
|
||||
#
|
||||
|
Loading…
x
Reference in New Issue
Block a user