Skip to content

Commit 954f206

Browse files
committed
Assignment 3
Completed http_server.py
1 parent f7f0dac commit 954f206

File tree

1 file changed

+72
-52
lines changed

1 file changed

+72
-52
lines changed

http_server.py

Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,45 @@
1+
# from os import path
12
import socket
23
import sys
4+
import os
35
import traceback
6+
import mimetypes
7+
8+
9+
root_dir = '/'.join([os.getcwd(), 'webroot'])
410

511
def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):
6-
"""
7-
returns a basic HTTP response
8-
Ex:
9-
response_ok(
10-
b"<html><h1>Welcome:</h1></html>",
11-
b"text/html"
12-
) ->
13-
14-
b'''
15-
HTTP/1.1 200 OK\r\n
16-
Content-Type: text/html\r\n
17-
\r\n
18-
<html><h1>Welcome:</h1></html>\r\n
19-
'''
20-
"""
12+
"""returns a basic HTTP response"""
2113

2214
# TODO: Implement response_ok
23-
return b""
15+
return b"\r\n".join([
16+
b"HTTP/1.1 200 OK",
17+
b"Content-Type: " + mimetype,
18+
b"",
19+
body,
20+
])
21+
2422

2523
def response_method_not_allowed():
2624
"""Returns a 405 Method Not Allowed response"""
2725

2826
# TODO: Implement response_method_not_allowed
29-
return b""
27+
return b"\r\n".join([
28+
b"HTTP/1.1 405 Method Not Allowed",
29+
b"",
30+
b"You can't do that on this server!",
31+
])
3032

3133

3234
def response_not_found():
3335
"""Returns a 404 Not Found response"""
3436

3537
# TODO: Implement response_not_found
36-
return b""
38+
return b"\r\n".join([
39+
b"HTTP/1.1 404 Not Found",
40+
b"",
41+
b"You can't do that on this server!",
42+
])
3743

3844

3945
def parse_request(request):
@@ -45,7 +51,13 @@ def parse_request(request):
4551
"""
4652

4753
# TODO: implement parse_request
48-
return ""
54+
method, path, version = request.split("\r\n")[0].split(" ")
55+
56+
if method != "GET":
57+
raise NotImplementedError
58+
59+
return path
60+
4961

5062
def response_path(path):
5163
"""
@@ -59,20 +71,6 @@ def response_path(path):
5971
6072
If the path does not map to a real location, it should raise an
6173
exception that the server can catch to return a 404 response.
62-
63-
Ex:
64-
response_path('/a_web_page.html') -> (b"<html><h1>North Carolina...",
65-
b"text/html")
66-
67-
response_path('/images/sample_1.png')
68-
-> (b"A12BCF...", # contents of sample_1.png
69-
b"image/png")
70-
71-
response_path('/') -> (b"images/, a_web_page.html, make_type.py,...",
72-
b"text/plain")
73-
74-
response_path('/a_page_that_doesnt_exist.html') -> Raises a NameError
75-
7674
"""
7775

7876
# TODO: Raise a NameError if the requested content is not present
@@ -85,11 +83,21 @@ def response_path(path):
8583
# If the path is "make_time.py", then you may OPTIONALLY return the
8684
# result of executing `make_time.py`. But you need only return the
8785
# CONTENTS of `make_time.py`.
88-
89-
content = b"not implemented"
90-
mime_type = b"not implemented"
9186

92-
return content, mime_type
87+
mime_type = "text/plain"
88+
89+
if path == "/":
90+
content = "\n".join([x for x in os.listdir(root_dir)]).encode()
91+
elif not "." in path:
92+
content = "\n".join([x for x in os.listdir(root_dir + path)]).encode()
93+
else:
94+
try:
95+
with open("".join([root_dir, path]), 'rb') as f:
96+
content = f.read()
97+
mime_type = mimetypes.guess_type(path)[0]
98+
except FileNotFoundError:
99+
raise NameError
100+
return content, mime_type.encode()
93101

94102

95103
def server(log_buffer=sys.stderr):
@@ -112,27 +120,39 @@ def server(log_buffer=sys.stderr):
112120
data = conn.recv(1024)
113121
request += data.decode('utf8')
114122

115-
if '\r\n\r\n' in request:
123+
if len(data) < 1024:
124+
break
125+
if b'\r\n\r\n' in request:
116126
break
117127

118128

119129
print("Request received:\n{}\n\n".format(request))
120130

121131
# TODO: Use parse_request to retrieve the path from the request.
122-
123-
# TODO: Use response_path to retrieve the content and the mimetype,
124-
# based on the request path.
125-
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-
)
135-
132+
try:
133+
path = parse_request(request)
134+
135+
# TODO: Use response_path to retrieve the content and the mimetype,
136+
# based on the request path.
137+
response = response_ok(
138+
body=b"Welcome to my web server",
139+
mimetype=b"text/plain"
140+
)
141+
142+
# TODO; If parse_request raised a NotImplementedError, then let
143+
# response be a method_not_allowed response. If response_path raised
144+
# a NameError, then let response be a not_found response. Else,
145+
# use the content and mimetype from response_path to build a
146+
# response_ok.
147+
except NotImplementedError:
148+
response = response_method_not_allowed()
149+
else:
150+
try:
151+
body, mimetype = response_path(path)
152+
except NameError:
153+
response = response_not_found()
154+
else:
155+
response = response_ok(body=body, mimetype=mimetype)
136156
conn.sendall(response)
137157
except:
138158
traceback.print_exc()

0 commit comments

Comments
 (0)