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/.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/__init__.py b/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/http_server.py b/http_server.py
index 58d7386..5457c11 100644
--- a/http_server.py
+++ b/http_server.py
@@ -1,6 +1,9 @@
import socket
import sys
+import os
import traceback
+import mimetypes
+import subprocess
def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):
"""
@@ -16,24 +19,45 @@ 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""
-
+ # """
+ # response = f"""HTTP/1.1 200 OK\r
+ # Content-Type:{mimetype}\r\n\r
+ # {body}
+ # """
+ if mimetype == "text/plain":
+ response = "HTTP/1.1 200 OK\r\n"
+ response += "Content-Type:{}\r\n".format(mimetype)
+ response += "\r\n"
+ response += "{}".format(body)
+
+ return response.encode()
+
+ else:
+ response = "HTTP/1.1 200 OK\r\n"
+ response += "Content-Type: {}\r\n".format(mimetype)
+ response += "\r\n"
+ response = response.encode()
+ response += body
+
+ return response
+
+
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 Method Not Allowed\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 Not Found\r
+ Content-Type: text/plain\r\n\r
+ Not Found\r"""
+ return response.encode()
def parse_request(request):
@@ -44,8 +68,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 +103,37 @@ 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)
+ content = '\r\n'.join(dir_list)
+ mime_type = "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", ".py" : "text/plain", ".bmp" : "image/bmp" }
+ name, extension = os.path.splitext(path)
+ mime_type = types.get(extension)
+ # print(mime_type)
+
+ if "text/plain" 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()
+
+
# 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,8 +142,8 @@ 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
@@ -114,25 +170,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.
-
+ 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 +206,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..ac32132 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):
"""
@@ -54,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
@@ -66,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):
"""
@@ -93,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
diff --git a/unit-tests.py b/unit_tests.py
similarity index 97%
rename from unit-tests.py
rename to 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 97a68ab..c9efc58 100644
Binary files a/webroot/favicon.ico and b/webroot/favicon.ico differ