From 7aaef5a939e53f8cf03806de87efedfe729e777a Mon Sep 17 00:00:00 2001 From: srepking Date: Sun, 13 Sep 2020 00:03:40 -0700 Subject: [PATCH] Repking Lesson 3 Assignment --- http_server.py | 111 ++++++++++++++++++++++++++++++++----------------- tests.py | 1 + unit-tests.py | 28 ++++++++++++- 3 files changed, 102 insertions(+), 38 deletions(-) diff --git a/http_server.py b/http_server.py index 58d7386..b9ac25d 100644 --- a/http_server.py +++ b/http_server.py @@ -1,6 +1,14 @@ import socket import sys import traceback +import logging +import os +import mimetypes + +mimetypes.add_type("image/jpeg", '.jpeg') +mimetypes.add_type("image/jpeg", '.jpg') + +logging.basicConfig(level=logging.INFO) def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): """ @@ -19,21 +27,27 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): ''' """ - # TODO: Implement response_ok - return b"" + return b"\r\n".join([ + b"HTTP/1.1 200 OK", + b"Content-Type: " + mimetype, + b"", + body, + ]) 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"HTTP/1.1 404 Not Found" def parse_request(request): @@ -44,8 +58,12 @@ def parse_request(request): NotImplementedError if the method of the request is not GET. """ - # 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): """ @@ -75,22 +93,36 @@ def response_path(path): """ - # TODO: Raise a NameError if the requested content is not present - # under webroot. - # TODO: Fill in the appropriate content and mime_type give the path. - # See the assignment guidelines for help on "mapping mime-types", though - # you might need to create a special case for handling make_time.py - # - # 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`. + head = os.path.split(path)[0] + tail = os.path.split(path)[1] + logging.debug("the head is: {}".format(head)) + logging.debug("the tail is: {}".format(tail)) + file_path = os.path.join('webroot'+head, tail) + logging.debug("the file_path is: {}".format(file_path)) + if os.path.isfile(file_path) is True: + logging.debug("File is found") + with open(file_path, "rb") as f: + content = f.read() + tail = os.path.split(path)[1] + print('File_name: {}'.format(tail)) + mime_type = mimetypes.guess_type(tail)[0].encode() + print(mime_type) + return content, mime_type + + elif os.path.isdir(file_path): + logging.debug("Directory is found") + mime_type = b"text/plain" + file_list = os.listdir(file_path) #list of files + file_string = ','.join(file_list) #string of files + content = file_string.encode() #encoded string + logging.debug("Contents in Directory: {}".format(content)) + return content, mime_type + + else: + logging.debug("Nothing is found") + raise NameError - content = b"not implemented" - mime_type = b"not implemented" - - return content, mime_type - def server(log_buffer=sys.stderr): address = ('127.0.0.1', 10000) @@ -114,24 +146,29 @@ 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. - - # TODO: Use response_path to retrieve the content and the mimetype, - # based on the request 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" - ) + try: + # Use parse_request to retrieve the path from the request. + path = parse_request(request) + # Use response_path to retrieve the content and the mimetype, + # based on the request path. + content, mime_type = response_path(path) + response = response_ok( + body=content, + mimetype=mime_type) + + # If parse_request raised a NotImplementedError, then let + # response be a method_not_allowed response. + except NotImplementedError: + response = response_method_not_allowed() + + # 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. + except NameError: + response = response_not_found() conn.sendall(response) except: diff --git a/tests.py b/tests.py index 21da57e..b6bda68 100644 --- a/tests.py +++ b/tests.py @@ -2,6 +2,7 @@ import subprocess import http.client import os +import logging class WebTestCase(unittest.TestCase): diff --git a/unit-tests.py b/unit-tests.py index a0c657a..8268dcd 100644 --- a/unit-tests.py +++ b/unit-tests.py @@ -5,6 +5,7 @@ class TestCase(unittest.TestCase): + #@unittest.skip("Skipping") def test_response_ok(self): mimetype = b"image/bmp" body = b"foo" @@ -53,10 +54,22 @@ def test_response_path_file(self): content, mime_type = http_server.response_path(path) self.assertEqual(b"text/html", mime_type) - + with open(os.path.join("webroot", "a_web_page.html"), "rb") as f: self.assertEqual(f.read(), content) + def test_response_path_image(self): + file = 'images/Sample_Scene_Balls.jpg' + web_path = '/' + file + + content, mime_type = http_server.response_path(web_path) + + + self.assertEqual(b"image/jpeg", mime_type) + + with open(os.path.join("webroot", file), "rb") as f: + self.assertEqual(f.read(), content) + def test_response_path_dir(self): path = "/" @@ -67,6 +80,19 @@ def test_response_path_dir(self): self.assertIn(b"sample.txt", content) self.assertIn(b"a_web_page.html", content) + def test_images_index(self): + """ + A call to /images/ yields a list of files in the images directory + """ + + path = "/images" + + content, mime_type = http_server.response_path(path) + + self.assertIn(b"JPEG_example.jpg", content) + self.assertIn(b"sample_1.png", content) + self.assertIn(b"Sample_Scene_Balls.jpg", content) + def test_response_path_not_found(self): path = "/foo/bar/baz/doesnt/exist"