Skip to content

Commit 2bdd602

Browse files
committed
Initial commit
1 parent f7f0dac commit 2bdd602

File tree

1 file changed

+51
-37
lines changed

1 file changed

+51
-37
lines changed

http_server.py

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import socket
22
import sys
33
import traceback
4+
import os
5+
import mimetypes
46

57
def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):
68
"""
@@ -19,22 +21,30 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):
1921
'''
2022
"""
2123

22-
# TODO: Implement response_ok
23-
return b""
24+
return b"\r\n".join([
25+
b"HTTP/1.1 200 OK",
26+
b"Content-Type: " + mimetype,
27+
b"",
28+
body,
29+
])
2430

2531
def response_method_not_allowed():
2632
"""Returns a 405 Method Not Allowed response"""
2733

28-
# TODO: Implement response_method_not_allowed
29-
return b""
30-
34+
return b"\r\n".join([
35+
b"HTTP/1.1 405 Method Not Allowed",
36+
b"",
37+
b"There's no place for a method like that on a server like this.",
38+
])
3139

3240
def response_not_found():
3341
"""Returns a 404 Not Found response"""
3442

35-
# TODO: Implement response_not_found
36-
return b""
37-
43+
return b"\r\n".join([
44+
b"HTTP/1.1 404 Not Found",
45+
b"",
46+
b"Looks like you're barking up the wrong tree, my friend.",
47+
])
3848

3949
def parse_request(request):
4050
"""
@@ -44,8 +54,14 @@ def parse_request(request):
4454
NotImplementedError if the method of the request is not GET.
4555
"""
4656

47-
# TODO: implement parse_request
48-
return ""
57+
# The path is always in the first line of an HTTP request.
58+
# The first line is structured as {method} {path} {version} (e.g. GET /library HTTP/1.1).
59+
method, path, version = request.split("\r\n")[0].split(" ")
60+
61+
if method != "GET":
62+
raise NotImplementedError
63+
64+
return path
4965

5066
def response_path(path):
5167
"""
@@ -75,19 +91,24 @@ def response_path(path):
7591
7692
"""
7793

78-
# TODO: Raise a NameError if the requested content is not present
79-
# under webroot.
94+
# os.path.abspath('.') returns the path of the current directory
95+
path = os.path.abspath('.') + '/webroot' + path
8096

81-
# TODO: Fill in the appropriate content and mime_type give the path.
82-
# See the assignment guidelines for help on "mapping mime-types", though
83-
# you might need to create a special case for handling make_time.py
84-
#
85-
# If the path is "make_time.py", then you may OPTIONALLY return the
86-
# result of executing `make_time.py`. But you need only return the
87-
# CONTENTS of `make_time.py`.
88-
89-
content = b"not implemented"
90-
mime_type = b"not implemented"
97+
# If the path leads to a file, serve it up
98+
if os.path.isfile(path):
99+
filetype = path[path.rfind("."):]
100+
mime_type = mimetypes.types_map[filetype].encode()
101+
with open(path, 'rb') as file:
102+
content = file.read()
103+
104+
# If the path leads to a directory, list its contents
105+
elif os.path.isdir(path):
106+
content = ", ".join(os.listdir(path)).encode()
107+
mime_type = b"text/plain"
108+
109+
# If the path doesn't exist, raise a NameError
110+
else:
111+
raise NameError
91112

92113
return content, mime_type
93114

@@ -115,23 +136,18 @@ def server(log_buffer=sys.stderr):
115136
if '\r\n\r\n' in request:
116137
break
117138

118-
119139
print("Request received:\n{}\n\n".format(request))
120140

121-
# TODO: Use parse_request to retrieve the path from the request.
141+
try:
142+
path = parse_request(request)
143+
body, mime_type = response_path(path)
144+
response = response_ok(body, mime_type)
122145

123-
# TODO: Use response_path to retrieve the content and the mimetype,
124-
# based on the request path.
146+
except NotImplementedError:
147+
response = response_method_not_allowed()
125148

126-
# TODO; If parse_request raised a NotImplementedError, then let
127-
# response be a method_not_allowed response. If response_path raised
128-
# a NameError, then let response be a not_found response. Else,
129-
# use the content and mimetype from response_path to build a
130-
# response_ok.
131-
response = response_ok(
132-
body=b"Welcome to my web server",
133-
mimetype=b"text/plain"
134-
)
149+
except NameError:
150+
response = response_not_found()
135151

136152
conn.sendall(response)
137153
except:
@@ -149,5 +165,3 @@ def server(log_buffer=sys.stderr):
149165
if __name__ == '__main__':
150166
server()
151167
sys.exit(0)
152-
153-

0 commit comments

Comments
 (0)