From cffe84e62cf29fb0b3534b272219492c0ea705c2 Mon Sep 17 00:00:00 2001 From: Clemente Fortuna Date: Wed, 27 May 2020 19:38:59 -0400 Subject: [PATCH 1/2] submission of L03 assignment, with the ability to execute make_time.py, and all tests passing. --- .temp_space.html | 7 ++ http_server.py | 148 ++++++++++++++++++++++++++++++++++++------- tests.py | 6 +- unit-tests.py | 8 +-- webroot/make_time.py | 9 ++- 5 files changed, 145 insertions(+), 33 deletions(-) create mode 100644 .temp_space.html diff --git a/.temp_space.html b/.temp_space.html new file mode 100644 index 0000000..5b94501 --- /dev/null +++ b/.temp_space.html @@ -0,0 +1,7 @@ + + + +

The time is:

+

2020-05-27T19:36:58.622811

+ + diff --git a/http_server.py b/http_server.py index 58d7386..ec4b175 100644 --- a/http_server.py +++ b/http_server.py @@ -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: @@ -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): @@ -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): """ @@ -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 @@ -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() @@ -149,5 +253,3 @@ def server(log_buffer=sys.stderr): if __name__ == '__main__': server() sys.exit(0) - - diff --git a/tests.py b/tests.py index 21da57e..d5124a0 100644 --- a/tests.py +++ b/tests.py @@ -49,7 +49,6 @@ 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 @@ -57,6 +56,7 @@ def test_get_sample_text_content(self): 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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/unit-tests.py b/unit-tests.py index a0c657a..2614adb 100644 --- a/unit-tests.py +++ b/unit-tests.py @@ -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) diff --git a/webroot/make_time.py b/webroot/make_time.py index b69acf3..6ff41a1 100644 --- a/webroot/make_time.py +++ b/webroot/make_time.py @@ -10,13 +10,12 @@ time_str = datetime.datetime.now().isoformat() -html = """ - +html = """ +

The time is:

-

%s

+

%s

-
-""" % time_str +""" % time_str print(html) From b89f08f97a2ad4b6420ad47b69a5045bb742ddb1 Mon Sep 17 00:00:00 2001 From: Clemente Fortuna Date: Wed, 27 May 2020 19:42:42 -0400 Subject: [PATCH 2/2] cleared out hidden temporary html file --- .temp_space.html | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.temp_space.html b/.temp_space.html index 5b94501..e69de29 100644 --- a/.temp_space.html +++ b/.temp_space.html @@ -1,7 +0,0 @@ - - - -

The time is:

-

2020-05-27T19:36:58.622811

- -