Skip to content

submission of L03 with extra credit (make_time.py executable & servable) #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .temp_space.html
Empty file.
148 changes: 125 additions & 23 deletions http_server.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import socket
import sys
import traceback
import webroot
import mimetypes
import os
import io
from contextlib import redirect_stdout

def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):

def response_ok(content=b"This is a minimal response", mimetype=b"text/plain"):
"""
returns a basic HTTP response
Ex:
Expand All @@ -20,20 +26,35 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):
"""

# TODO: Implement response_ok
return b""
# Needs to make use of body and MIME type argument.
return b"\r\n".join([
b"HTTP/1.1 200 OK",
b"Content-Type: " + mimetype,
b"",
content,
])


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

# TODO: Implement response_method_not_allowed
return b""
return b"\r\n".join([
b"HTTP/1.1 405 Method Not Allowed",
b"",
b"You can't do that on this server!"
])


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

# TODO: Implement response_not_found
return b""
return b"\r\n".join([
b"HTTP/1.1 404 Not Found",
b"",
b"Resource not on on this server!"
])


def parse_request(request):
Expand All @@ -45,7 +66,13 @@ def parse_request(request):
"""

# TODO: implement parse_request
return ""
method, path, version = request.split("\r\n")[0].split(" ")

if method != "GET":
raise NotImplementedError

return path


def response_path(path):
"""
Expand Down Expand Up @@ -85,9 +112,70 @@ def response_path(path):
# If the path is "make_time.py", then you may OPTIONALLY return the
# result of executing `make_time.py`. But you need only return the
# CONTENTS of `make_time.py`.

content = b"not implemented"
mime_type = b"not implemented"

full_path = os.getcwd() + '/webroot/' + path

directory = ['/']
os.chdir(os.getcwd() + '/webroot')
walk_result = os.walk('.')
for line_result in walk_result:
if line_result[1] != []:
for dir_result in line_result[1]:
directory.append('/' + line_result[0][1:] + dir_result)
directory.append('/' + line_result[0][1:] + dir_result + '/')
for file_result in line_result[2]:
directory.append(line_result[0][1:] + '/' + file_result)
os.chdir('..')

if path not in directory:
raise NameError

elif '.' not in path:
mime_type = b'text/plain'
os.chdir(os.getcwd() + '/webroot')
path_result = os.walk('.' + path)
content_uncoded = ''
for path_result_item in path_result:
content_uncoded += str(path_result_item)
content = content_uncoded.encode('utf8')
os.chdir('..')

else:
mime_type = mimetypes.guess_type(path)[0].encode('utf8')
content = b''
if mime_type == b'text/html':
with open(full_path, 'r') as html_file:
for line in html_file.readlines():
content += line.encode('utf8')

if mime_type[:5] == b'image':
with open(full_path, 'rb') as image_file:
for line in image_file.readlines():
content += line

if mime_type == b'text/plain':
with open(full_path, 'r') as plain_text_file:
for line in plain_text_file.readlines():
content += line.encode('utf8')

if mime_type == b'text/x-python':
content_uncoded_1 = ''
content_uncoded_2 = ''
with open(full_path, 'r') as python_file, open('.temp_space.html', 'w') as exec_file:
for line in python_file.readlines():
content_uncoded_1 += line
f1 = io.StringIO()
with redirect_stdout(f1):
exec(content_uncoded_1)
exec_file.writelines(f1.getvalue())
with open(os.getcwd() + '/.temp_space.html', 'r') as run_file:
for line in run_file.readlines():
content_uncoded_2 += line
content += content_uncoded_2.encode('utf8')
mime_type = b'text/html'

# content = b"not implemented"
# mime_type = b"not implemented"

return content, mime_type

Expand All @@ -114,30 +202,46 @@ def server(log_buffer=sys.stderr):

if '\r\n\r\n' in request:
break


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

# TODO: Use parse_request to retrieve the path from the request.
try:
path = parse_request(request)
# print('hey path is {}'.format(path))

# TODO: Use response_path to retrieve the content and the mimetype,
# based on the request path.

# TODO: Use response_path to retrieve the content and the mimetype,
# based on the request path.
content, mime_type = response_path(path)

# TODO; If parse_request raised a NotImplementedError, then let
# response be a method_not_allowed response. If response_path raised
# a NameError, then let response be a not_found response. Else,
# use the content and mimetype from response_path to build a
# response_ok.
response = response_ok(
body=b"Welcome to my web server",
mimetype=b"text/plain"
)
# TODO; If parse_request raised a NotImplementedError, then let
# response be a method_not_allowed response. If response_path raised
# a NameError, then let response be a not_found response. Else,
# use the content and mimetype from response_path to build a
# response_ok.

response = response_ok(
content=content,
mimetype=mime_type
)

# response = response_ok(
# content=b"Welcome to my web server!",
# mimetype=b"text/plain"
# )

except NotImplementedError:
response = response_method_not_allowed()

except NameError:
response = response_not_found()

conn.sendall(response)
except:
traceback.print_exc()
finally:
conn.close()
conn.close()

except KeyboardInterrupt:
sock.close()
Expand All @@ -149,5 +253,3 @@ def server(log_buffer=sys.stderr):
if __name__ == '__main__':
server()
sys.exit(0)


6 changes: 5 additions & 1 deletion tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ def test_post_yields_method_not_allowed(self):

self.assertEqual(response.getcode(), 405)


def test_get_sample_text_content(self):
"""
A call to /sample.txt returns the correct body
"""
file = 'sample.txt'

local_path = os.path.join('webroot', *file.split('/'))
# local_path = os.path.join(*file.split('/'))
web_path = '/' + file
error_comment = "Error encountered while visiting " + web_path

Expand Down Expand Up @@ -88,6 +88,7 @@ def test_get_sample_scene_balls_jpeg(self):
file = 'images/Sample_Scene_Balls.jpg'

local_path = os.path.join('webroot', *file.split('/'))
# local_path = os.path.join(*file.split('/'))
web_path = '/' + file
error_comment = "Error encountered while visiting " + web_path

Expand Down Expand Up @@ -119,6 +120,7 @@ def test_get_sample_1_png(self):
file = 'images/sample_1.png'

local_path = os.path.join('webroot', *file.split('/'))
# local_path = os.path.join(*file.split('/'))
web_path = '/' + file
error_comment = "Error encountered while visiting " + web_path

Expand Down Expand Up @@ -163,6 +165,7 @@ def test_images_index(self):

directory = 'images'
local_path = os.path.join('webroot', directory)
# local_path = os.path.join(directory)
web_path = '/' + directory
error_comment = "Error encountered while visiting " + web_path

Expand All @@ -179,6 +182,7 @@ def test_root_index(self):

directory = ''
local_path = os.path.join('webroot', directory)
# local_path = os.path.join(directory)
web_path = '/' + directory
error_comment = "Error encountered while visiting " + web_path

Expand Down
8 changes: 4 additions & 4 deletions unit-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ class TestCase(unittest.TestCase):

def test_response_ok(self):
mimetype = b"image/bmp"
body = b"foo"
content = b"foo"

response = http_server.response_ok(body=body, mimetype=mimetype)
response = http_server.response_ok(content=content, mimetype=mimetype)
str_response = response.decode()

self.assertIn("\r\n\r\n", str_response)

str_header, str_body = str_response.split("\r\n\r\n")
str_header, str_content = str_response.split("\r\n\r\n")

self.assertEqual(body.decode(), str_body)
self.assertEqual(content.decode(), str_content)
self.assertEqual("HTTP/1.1 200 OK",
str_header.splitlines()[0])
self.assertIn("Content-Type: " + mimetype.decode(), str_header)
Expand Down
9 changes: 4 additions & 5 deletions webroot/make_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@

time_str = datetime.datetime.now().isoformat()

html = """
<http>
html = """<!DOCTYPE html>
<html>
<body>
<h2> The time is: </h2>
<p> %s <p>
<p> %s </p>
</body>
</http>
""" % time_str
</html>""" % time_str

print(html)