Steps 1 & 2 completed.
This commit is contained in:
parent
9648a058e0
commit
6f350bf5ef
|
@ -86,16 +86,15 @@ def handle_client(c: socket.socket, addr: tuple[str, int], root:str):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
buf = c.recv(_BUF_SIZE)
|
# Parse the request to get the headers - call parse_request().
|
||||||
req = dict()
|
|
||||||
|
|
||||||
# Prepare our reply.
|
# Prepare our reply.
|
||||||
reply, code = prepare_resource(root, req)
|
# If we get a GET verb from the request header, then call prepare_resource().
|
||||||
|
# Otherwise, prepare a reply with a "Non Implemented" status code.
|
||||||
|
|
||||||
# Send the reply back.
|
# Send the reply back.
|
||||||
c.send(reply)
|
|
||||||
|
|
||||||
# Optionally trace the action in the logs.
|
# Trace the action in the logs.
|
||||||
|
|
||||||
# Close the connection.
|
# Close the connection.
|
||||||
c.close()
|
c.close()
|
||||||
|
@ -125,6 +124,11 @@ def prepare_resource(root: str, req: dict):
|
||||||
content = b"Hello World!"
|
content = b"Hello World!"
|
||||||
content_type = "text/html"
|
content_type = "text/html"
|
||||||
|
|
||||||
|
# Call resolve_location().
|
||||||
|
# If an empty string is returned, the resource is not found.
|
||||||
|
# If a path is returned, get the content_type, the resource and the status code.
|
||||||
|
|
||||||
|
# Then call prepare_reply to build the final reply.
|
||||||
return prepare_reply(content, content_type, code)
|
return prepare_reply(content, content_type, code)
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,20 +169,11 @@ def prepare_reply(content: bytes, content_type: str, code: int):
|
||||||
The status code for the reply.
|
The status code for the reply.
|
||||||
"""
|
"""
|
||||||
# Prepare status code
|
# Prepare status code
|
||||||
http_code_dict = get_http_code(code)
|
code = 1234
|
||||||
if code != 200:
|
|
||||||
content = http_code_dict['html'].encode()
|
|
||||||
content_type = get_http_content_type('html')+"; charset=utf-8"
|
|
||||||
|
|
||||||
# Prepare headers, including content-type, date, content-length, server.
|
# Prepare headers, including content-type, date, content-length, server.
|
||||||
header = f"""HTTP/1.0 {http_code_dict['header']}
|
header = ''.encode()
|
||||||
Content-Type: {content_type}
|
|
||||||
Date: {now_rfc2616()}
|
|
||||||
Content-Length: {len(content)}
|
|
||||||
Server: RegardeMamanJeFaisUnServeurWeb/0.1
|
|
||||||
|
|
||||||
""".encode()
|
|
||||||
|
|
||||||
return header + content, code
|
return header + content, code
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,8 @@ def parse_request(buf: bytes) -> dict[str, dict]:
|
||||||
ValueError
|
ValueError
|
||||||
The request is not valid HTTP.
|
The request is not valid HTTP.
|
||||||
"""
|
"""
|
||||||
if buf == b'':
|
req_head = dict()
|
||||||
raise ValueError("Received empty request")
|
|
||||||
lines = buf.decode('utf-8').strip().splitlines()
|
|
||||||
|
|
||||||
req_head = parse_request_head(lines[0])
|
|
||||||
req_params = dict()
|
req_params = dict()
|
||||||
if len(lines) > 1:
|
|
||||||
req_params = parse_request_params(lines[1:])
|
|
||||||
|
|
||||||
return dict(
|
return dict(
|
||||||
head=req_head,
|
head=req_head,
|
||||||
|
@ -96,13 +90,12 @@ def parse_request_head(line: str) -> dict[str, str]:
|
||||||
ValueError
|
ValueError
|
||||||
The request header is not valid HTTP.
|
The request header is not valid HTTP.
|
||||||
"""
|
"""
|
||||||
fields = line.split(' ')
|
|
||||||
if len(fields) != 3:
|
pass
|
||||||
raise ValueError(f"Request header is invalid: {line}")
|
|
||||||
|
|
||||||
return dict(
|
return dict(
|
||||||
verb=fields[0].upper(),
|
verb=None,
|
||||||
resource=fields[1]
|
resource=None
|
||||||
)
|
)
|
||||||
|
|
||||||
def parse_request_params(lines: list[str]) -> dict[str, str]:
|
def parse_request_params(lines: list[str]) -> dict[str, str]:
|
||||||
|
@ -131,13 +124,7 @@ def parse_request_params(lines: list[str]) -> dict[str, str]:
|
||||||
The provided lines are not valid HTTP.
|
The provided lines are not valid HTTP.
|
||||||
"""
|
"""
|
||||||
params = dict()
|
params = dict()
|
||||||
for l in lines:
|
|
||||||
kv = l.strip().split(': ')
|
|
||||||
|
|
||||||
if len(kv) != 2 or len(kv[0]) == 0 or len(kv[1]) == 0:
|
|
||||||
raise ValueError(f"Request line is not a valid key/value pair: {l}")
|
|
||||||
|
|
||||||
params[kv[0]] = kv[1]
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,20 +86,19 @@ def handle_client(c: socket.socket, addr: tuple[str, int], root:str):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Read the socket.
|
||||||
buf = c.recv(_BUF_SIZE)
|
buf = c.recv(_BUF_SIZE)
|
||||||
req = parse_request(buf)
|
print(buf)
|
||||||
|
|
||||||
|
# Parse the request to get the headers - call parse_request().
|
||||||
|
|
||||||
# Prepare our reply.
|
# Prepare our reply.
|
||||||
if req['head']['verb'] == 'GET':
|
# If we get a GET verb from the request header, then call prepare_resource().
|
||||||
reply, code = prepare_resource(root, req)
|
# Otherwise, prepare a reply with a "Non Implemented" status code.
|
||||||
else:
|
|
||||||
# Not implemented: we treat only GET calls for now.
|
|
||||||
reply, code = prepare_reply(b"", "", 501)
|
|
||||||
|
|
||||||
# Send the reply back.
|
# Send the reply back.
|
||||||
c.send(reply)
|
|
||||||
|
|
||||||
# Optionally trace the action in the logs.
|
# Trace the action in the logs.
|
||||||
|
|
||||||
# Close the connection.
|
# Close the connection.
|
||||||
c.close()
|
c.close()
|
||||||
|
@ -129,6 +128,11 @@ def prepare_resource(root: str, req: dict):
|
||||||
content = b"Hello World!"
|
content = b"Hello World!"
|
||||||
content_type = "text/html"
|
content_type = "text/html"
|
||||||
|
|
||||||
|
# Call resolve_location().
|
||||||
|
# If an empty string is returned, the resource is not found.
|
||||||
|
# If a path is returned, get the content_type, the resource and the status code.
|
||||||
|
|
||||||
|
# Then call prepare_reply to build the final reply.
|
||||||
return prepare_reply(content, content_type, code)
|
return prepare_reply(content, content_type, code)
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,20 +173,11 @@ def prepare_reply(content: bytes, content_type: str, code: int):
|
||||||
The status code for the reply.
|
The status code for the reply.
|
||||||
"""
|
"""
|
||||||
# Prepare status code
|
# Prepare status code
|
||||||
http_code_dict = get_http_code(code)
|
code = 1234
|
||||||
if code != 200:
|
|
||||||
content = http_code_dict['html'].encode()
|
|
||||||
content_type = get_http_content_type('html')+"; charset=utf-8"
|
|
||||||
|
|
||||||
# Prepare headers, including content-type, date, content-length, server.
|
# Prepare headers, including content-type, date, content-length, server.
|
||||||
header = f"""HTTP/1.0 {http_code_dict['header']}
|
header = ''.encode()
|
||||||
Content-Type: {content_type}
|
|
||||||
Date: {now_rfc2616()}
|
|
||||||
Content-Length: {len(content)}
|
|
||||||
Server: RegardeMamanJeFaisUnServeurWeb/0.1
|
|
||||||
|
|
||||||
""".encode()
|
|
||||||
|
|
||||||
return header + content, code
|
return header + content, code
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue