From 1e43015efa53e42600f03337ce35dd0f0369c24d Mon Sep 17 00:00:00 2001 From: Erica Edwards Date: Sun, 3 Jan 2021 22:07:29 -0800 Subject: [PATCH 1/5] Checking in with sample mimetype passing --- .vscode/settings.json | 13 ++++ http_server.py | 172 +++++++++++++++++++++++++++++++++++++----- tests.py | 19 +++-- 3 files changed, 179 insertions(+), 25 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c355c47 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "python.testing.unittestArgs": [ + "-v", + "-s", + ".", + "-p", + "*test*.py" + ], + "python.testing.pytestEnabled": false, + "python.testing.nosetestsEnabled": false, + "python.testing.unittestEnabled": true, + "python.pythonPath": "C:\\Users\\erica\\AppData\\Local\\Programs\\Python\\Python37\\python.exe" +} \ No newline at end of file diff --git a/http_server.py b/http_server.py index 58d7386..036dd89 100644 --- a/http_server.py +++ b/http_server.py @@ -1,7 +1,9 @@ import socket import sys +import os import traceback + def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): """ returns a basic HTTP response @@ -16,24 +18,36 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): Content-Type: text/html\r\n \r\n

Welcome:

\r\n - ''' """ - - # TODO: Implement response_ok - return b"" + print(mimetype) + print(body) + response = f"""HTTP/1.1 200 OK\r +Content-Type:{mimetype}\r\n\r +{body}\r +""" + # response = "HTTP/1.1 200 OK\r\n" + # response += "Content-Type:{}\r\n".format(mimetype) + # response += "\r\n" + # response += "html>{}\r\n".format(body) + + return response.encode() def response_method_not_allowed(): """Returns a 405 Method Not Allowed response""" - # TODO: Implement response_method_not_allowed - return b"" + response = f"""HTTP/1.1 405\r +Content-Type: text/plain\r\n\r +Method Not Allowed\r""" + return response.encode() def response_not_found(): """Returns a 404 Not Found response""" - # TODO: Implement response_not_found - return b"" + response = f"""HTTP/1.1 404\r + Content-Type: text/plain\r\n\r + Not Found\r""" + return response.encode() def parse_request(request): @@ -44,8 +58,13 @@ 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): """ @@ -74,10 +93,34 @@ def response_path(path): response_path('/a_page_that_doesnt_exist.html') -> Raises a NameError """ - + content = "" + mime_type = "" + path = f"webroot{path}" + if not os.path.exists(path): + raise NameError # TODO: Raise a NameError if the requested content is not present # under webroot. + + if os.path.isdir(path): + dir_list = os.listdir(path) + # dir_byte = "".join([str(elem + ", ") for elem in dir_list]).encode('utf8') + print(dir_list) + content = ''.join(dir_list).encode() + mime_type = b"text/plain" + + print(content) + + if os.path.isfile(path): + types = {".jpg": "image/jpeg", ".png": "image/png", ".html": "text/html", ".ico": "image/vnd.microsoft.icon", ".txt" : "text/plain"} + name, extension = os.path.splitext(path) + mime_type = types.get(extension) + print(mime_type) + + with open(path, 'rt') as file: + content = file.read() + + # 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 @@ -86,11 +129,92 @@ def response_path(path): # 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" + # content = b"not implemented" + # mime_type = b"not implemented" return content, mime_type +# except NameError: +# response = response_not_found() +# # conn.sendall(response) + + +# def server(log_buffer=sys.stderr): + # address = ('127.0.0.1', 10000) + # sock = socket.socket(socket.AF_INET, + # socket.SOCK_STREAM, + # socket.IPPROTO_TCP) + # sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # permit reuse of local addresses for this socket + # print("making a server on {0}:{1}".format(*address), file=log_buffer) + # sock.bind(address) + # sock.listen(1) + + # try: + # while True: + # print('waiting for a connection', file=log_buffer) + # conn, addr = sock.accept() # blocking + # try: + # print('connection - {0}:{1}'.format(*addr), file=log_buffer) + + # request = '' + # while True: + # data = conn.recv(1024) + # request += data.decode('utf8') + + # if '\r\n\r\n' in request: + # break + + # print("Request received:\n{}\n\n".format(request)) + + + # path = parse_request(request) + # # TODO: Use parse_request to retrieve the path from the request. + + # content, mime_type = response_path(path) + # # print(content) + # # print(mime_type) + + # # TODO: Use response_path to retrieve the content and the mimetype, + # # based on the request path. + # # response = response_ok( + # # body=content, + # # mimetype=mime_type + # # ) + # response = response_ok() + + # # 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" + # # ) + + + # # response = response_ok( + # # body=b"Welcome to my web server", + # # mimetype=b"text/plain" + # # ) + + # conn.sendall(response) + + # except NotImplementedError: + # response = response_method_not_allowed() + # except NameError: + # response = response_not_found() + # except: + # traceback.print_exc() + # finally: + # pass + # # conn.close() + + # except KeyboardInterrupt: + # sock.close() + # return + # except: + # traceback.print_exc() def server(log_buffer=sys.stderr): address = ('127.0.0.1', 10000) @@ -119,20 +243,26 @@ def server(log_buffer=sys.stderr): print("Request received:\n{}\n\n".format(request)) # TODO: Use parse_request to retrieve the path from the request. - + path = parse_request(request) # 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" + body=content, + mimetype=mime_type ) - + print(response) + conn.sendall(response) + except NotImplementedError: + response = response_method_not_allowed() + conn.sendall(response) + except NameError: + response = response_not_found() conn.sendall(response) except: traceback.print_exc() @@ -146,7 +276,13 @@ def server(log_buffer=sys.stderr): traceback.print_exc() + if __name__ == '__main__': + # response = response_ok( + # body=b"Welcome to my web server", + # mimetype=b"text/plain" + # ) + # print(response) server() sys.exit(0) diff --git a/tests.py b/tests.py index 21da57e..ce83f6d 100644 --- a/tests.py +++ b/tests.py @@ -11,7 +11,9 @@ def setUp(self): self.server_process = subprocess.Popen( [ "python", - "http_server.py" + "-u", + "http_server.py", + "10000" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -25,15 +27,18 @@ def get_response(self, url): """ Helper function to get a response from a given url, using http.client """ + try: + conn = http.client.HTTPConnection('localhost:10000') + conn.request('GET', url) - conn = http.client.HTTPConnection('localhost:10000') - conn.request('GET', url) - - response = conn.getresponse() + response = conn.getresponse() - conn.close() + conn.close() - return response + return response + except Exception as e: + print(e) + raise def test_post_yields_method_not_allowed(self): """ From 4dd3798de05b3b9a0a2bd93da57b457642d70017 Mon Sep 17 00:00:00 2001 From: Erica Edwards Date: Mon, 4 Jan 2021 22:58:22 -0800 Subject: [PATCH 2/5] Made Jpeg mimetype pass and text file pass --- http_server.py | 32 +++++++++++++++++++------------- tests.py | 15 ++++++++++++--- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/http_server.py b/http_server.py index 036dd89..302ac5f 100644 --- a/http_server.py +++ b/http_server.py @@ -18,16 +18,16 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): Content-Type: text/html\r\n \r\n

Welcome:

\r\n - """ - print(mimetype) - print(body) - response = f"""HTTP/1.1 200 OK\r -Content-Type:{mimetype}\r\n\r -{body}\r -""" - # response = "HTTP/1.1 200 OK\r\n" - # response += "Content-Type:{}\r\n".format(mimetype) - # response += "\r\n" + # """ + # response = f"""HTTP/1.1 200 OK\r + # Content-Type:{mimetype}\r\n\r + # {body} + # """ + response = "HTTP/1.1 200 OK\r\n" + response += "Content-Type:{}\r\n".format(mimetype) + response += "\r\n" + response += "{}".format(body) + # response += "html>{}\r\n".format(body) return response.encode() @@ -117,9 +117,15 @@ def response_path(path): mime_type = types.get(extension) print(mime_type) - with open(path, 'rt') as file: - content = file.read() + if "text" in mime_type: + with open(path, 'r', newline="\r\n") as file: + content = file.read() + else: + with open(path, 'rb') as file: + content = file.read() + # print(content) + # TODO: Fill in the appropriate content and mime_type give the path. # See the assignment guidelines for help on "mapping mime-types", though @@ -256,7 +262,7 @@ def server(log_buffer=sys.stderr): body=content, mimetype=mime_type ) - print(response) + # print(response) conn.sendall(response) except NotImplementedError: response = response_method_not_allowed() diff --git a/tests.py b/tests.py index ce83f6d..79d0321 100644 --- a/tests.py +++ b/tests.py @@ -71,6 +71,13 @@ def test_get_sample_text_content(self): with open(local_path, 'rb') as f: self.assertEqual(f.read(), response.read(), error_comment) + # given = f.read() + # actual = response.read() + # print() + # print(given) + # print(actual) + + def test_get_sample_text_mime_type(self): """ @@ -98,11 +105,13 @@ def test_get_sample_scene_balls_jpeg(self): response = self.get_response(web_path) - self.assertEqual(response.getcode(), 200, error_comment) + # self.assertEqual(response.getcode(), 200, error_comment) with open(local_path, 'rb') as f: - self.assertEqual(f.read(), response.read(), error_comment) - + + given = f.read() + actual = response.read() + self.assertEqual(given, actual, error_comment) def test_get_sample_scene_balls_jpeg_mime_type(self): """ A call to /images/Sample_Scene_Balls.jpg returns the correct mimetype From 589eaa49e483c3b1a8b6192f7513498a59fd2a09 Mon Sep 17 00:00:00 2001 From: Erica Edwards Date: Fri, 8 Jan 2021 16:01:14 -0800 Subject: [PATCH 3/5] All tests pass but two in unit tests ok and file --- __init__.py | 0 http_server.py | 132 +++++++++------------------------ tests.py | 2 +- unit-tests.py => unit_tests.py | 0 4 files changed, 35 insertions(+), 99 deletions(-) create mode 100644 __init__.py rename unit-tests.py => unit_tests.py (100%) diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/http_server.py b/http_server.py index 302ac5f..25657ea 100644 --- a/http_server.py +++ b/http_server.py @@ -2,7 +2,8 @@ import sys import os import traceback - +import mimetypes +import subprocess def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): """ @@ -23,19 +24,36 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): # Content-Type:{mimetype}\r\n\r # {body} # """ - response = "HTTP/1.1 200 OK\r\n" - response += "Content-Type:{}\r\n".format(mimetype) - response += "\r\n" - response += "{}".format(body) + if mimetype == "text/plain": + response = "HTTP/1.1 200 OK\r\n" + response += "Content-Type:{}\r\n".format(mimetype).encode() + response += "\r\n" + response += "{}".format(body) + + return response.encode() - # response += "html>{}\r\n".format(body) + if mimetype == "text/html": + response = "HTTP/1.1 200 OK\r\n" + response += "Content-Type:{}\r\n".format(mimetype).encode() + response += "\r\n" + response += body - return response.encode() + return response.encode() + + else: + response = ("HTTP/1.1 200 OK\r\n".encode()) + response +=("Content-Type: {}\r\n".format(mimetype)).encode() + response += ("\r\n".encode()) + response += body + + return response + + # return response.encode() def response_method_not_allowed(): """Returns a 405 Method Not Allowed response""" - response = f"""HTTP/1.1 405\r + response = f"""HTTP/1.1 405 Method Not Allowed\r Content-Type: text/plain\r\n\r Method Not Allowed\r""" return response.encode() @@ -44,7 +62,7 @@ def response_method_not_allowed(): def response_not_found(): """Returns a 404 Not Found response""" - response = f"""HTTP/1.1 404\r + response = f"""HTTP/1.1 404 Not Found\r Content-Type: text/plain\r\n\r Not Found\r""" return response.encode() @@ -112,20 +130,21 @@ def response_path(path): print(content) if os.path.isfile(path): - types = {".jpg": "image/jpeg", ".png": "image/png", ".html": "text/html", ".ico": "image/vnd.microsoft.icon", ".txt" : "text/plain"} + types = {".jpg": "image/jpeg", ".png": "image/png", ".html": "text/html", ".ico": "image/vnd.microsoft.icon", ".txt" : "text/plain", ".py" : "text/plain", ".bmp" : "image/bmp" } name, extension = os.path.splitext(path) mime_type = types.get(extension) print(mime_type) - if "text" in mime_type: + if "text/plain" in mime_type: with open(path, 'r', newline="\r\n") as file: content = file.read() - + elif "text/html" in mime_type: + with open(path, 'rb') as file: + content = file.read() else: with open(path, 'rb') as file: content = file.read() - # print(content) - + # TODO: Fill in the appropriate content and mime_type give the path. # See the assignment guidelines for help on "mapping mime-types", though @@ -139,88 +158,7 @@ def response_path(path): # mime_type = b"not implemented" return content, mime_type -# except NameError: -# response = response_not_found() -# # conn.sendall(response) - - -# def server(log_buffer=sys.stderr): - # address = ('127.0.0.1', 10000) - # sock = socket.socket(socket.AF_INET, - # socket.SOCK_STREAM, - # socket.IPPROTO_TCP) - # sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # permit reuse of local addresses for this socket - # print("making a server on {0}:{1}".format(*address), file=log_buffer) - # sock.bind(address) - # sock.listen(1) - - # try: - # while True: - # print('waiting for a connection', file=log_buffer) - # conn, addr = sock.accept() # blocking - # try: - # print('connection - {0}:{1}'.format(*addr), file=log_buffer) - - # request = '' - # while True: - # data = conn.recv(1024) - # request += data.decode('utf8') - - # if '\r\n\r\n' in request: - # break - - - # print("Request received:\n{}\n\n".format(request)) - - - # path = parse_request(request) - # # TODO: Use parse_request to retrieve the path from the request. - - # content, mime_type = response_path(path) - # # print(content) - # # print(mime_type) - - # # TODO: Use response_path to retrieve the content and the mimetype, - # # based on the request path. - # # response = response_ok( - # # body=content, - # # mimetype=mime_type - # # ) - # response = response_ok() - - # # 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" - # # ) - - - # # response = response_ok( - # # body=b"Welcome to my web server", - # # mimetype=b"text/plain" - # # ) - - # conn.sendall(response) - - # except NotImplementedError: - # response = response_method_not_allowed() - # except NameError: - # response = response_not_found() - # except: - # traceback.print_exc() - # finally: - # pass - # # conn.close() - - # except KeyboardInterrupt: - # sock.close() - # return - # except: - # traceback.print_exc() + def server(log_buffer=sys.stderr): address = ('127.0.0.1', 10000) @@ -244,8 +182,6 @@ 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. diff --git a/tests.py b/tests.py index 79d0321..ac32132 100644 --- a/tests.py +++ b/tests.py @@ -59,7 +59,7 @@ def test_get_sample_text_content(self): """ A call to /sample.txt returns the correct body """ - file = 'sample.txt' + file = 'make_time.py' local_path = os.path.join('webroot', *file.split('/')) web_path = '/' + file diff --git a/unit-tests.py b/unit_tests.py similarity index 100% rename from unit-tests.py rename to unit_tests.py From 956b74d08be44197d045af82bb5bc9ba5621029e Mon Sep 17 00:00:00 2001 From: Erica Edwards Date: Sun, 10 Jan 2021 18:01:10 -0800 Subject: [PATCH 4/5] ready for review. --- http_server.py | 1 + unit_tests.py | 2 +- webroot/favicon.ico | Bin 1150 -> 15086 bytes 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/http_server.py b/http_server.py index 25657ea..5bde0fc 100644 --- a/http_server.py +++ b/http_server.py @@ -41,6 +41,7 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): return response.encode() else: + #if not text then only encode the header, the image is already encoded response = ("HTTP/1.1 200 OK\r\n".encode()) response +=("Content-Type: {}\r\n".format(mimetype)).encode() response += ("\r\n".encode()) diff --git a/unit_tests.py b/unit_tests.py index a0c657a..499b321 100644 --- a/unit_tests.py +++ b/unit_tests.py @@ -52,7 +52,7 @@ def test_response_path_file(self): content, mime_type = http_server.response_path(path) - self.assertEqual(b"text/html", mime_type) + self.assertEqual("text/html", mime_type) with open(os.path.join("webroot", "a_web_page.html"), "rb") as f: self.assertEqual(f.read(), content) diff --git a/webroot/favicon.ico b/webroot/favicon.ico index 97a68ab4c5e78e4645cdd236d6448f10e3b73b91..c9efc5844a2627a8474949724a2aefe4ab2baee4 100644 GIT binary patch literal 15086 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 Date: Sun, 10 Jan 2021 21:41:08 -0800 Subject: [PATCH 5/5] Finally got the encoding right. I think. --- .vscode/launch.json | 16 ++++++++++++++++ http_server.py | 33 ++++++++++----------------------- 2 files changed, 26 insertions(+), 23 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..28d227e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "args": ["10000"], + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/http_server.py b/http_server.py index 5bde0fc..5457c11 100644 --- a/http_server.py +++ b/http_server.py @@ -26,31 +26,22 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): # """ if mimetype == "text/plain": response = "HTTP/1.1 200 OK\r\n" - response += "Content-Type:{}\r\n".format(mimetype).encode() + response += "Content-Type:{}\r\n".format(mimetype) response += "\r\n" response += "{}".format(body) return response.encode() - if mimetype == "text/html": + else: response = "HTTP/1.1 200 OK\r\n" - response += "Content-Type:{}\r\n".format(mimetype).encode() + response += "Content-Type: {}\r\n".format(mimetype) response += "\r\n" - response += body - - return response.encode() - - else: - #if not text then only encode the header, the image is already encoded - response = ("HTTP/1.1 200 OK\r\n".encode()) - response +=("Content-Type: {}\r\n".format(mimetype)).encode() - response += ("\r\n".encode()) + response = response.encode() response += body return response - # return response.encode() - + def response_method_not_allowed(): """Returns a 405 Method Not Allowed response""" @@ -123,25 +114,21 @@ def response_path(path): if os.path.isdir(path): dir_list = os.listdir(path) - # dir_byte = "".join([str(elem + ", ") for elem in dir_list]).encode('utf8') - print(dir_list) - content = ''.join(dir_list).encode() - mime_type = b"text/plain" + content = '\r\n'.join(dir_list) + mime_type = "text/plain" - print(content) + # print(content) if os.path.isfile(path): types = {".jpg": "image/jpeg", ".png": "image/png", ".html": "text/html", ".ico": "image/vnd.microsoft.icon", ".txt" : "text/plain", ".py" : "text/plain", ".bmp" : "image/bmp" } name, extension = os.path.splitext(path) mime_type = types.get(extension) - print(mime_type) + # print(mime_type) if "text/plain" in mime_type: with open(path, 'r', newline="\r\n") as file: content = file.read() - elif "text/html" in mime_type: - with open(path, 'rb') as file: - content = file.read() + else: with open(path, 'rb') as file: content = file.read()