diff --git a/http_server.py b/http_server.py
index 58d7386..7fe7b45 100644
--- a/http_server.py
+++ b/http_server.py
@@ -1,66 +1,74 @@
import socket
import sys
import traceback
+import os
+import mimetypes
def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):
"""
returns a basic HTTP response
- Ex:
- response_ok(
- b"
Welcome:
",
- b"text/html"
- ) ->
-
- b'''
- HTTP/1.1 200 OK\r\n
- Content-Type: text/html\r\n
- \r\n
- Welcome:
\r\n
- '''
+ Ex:
+ response_ok(
+ b"Welcome:
",
+ b"text/html"
+ ) ->
+
+ b'''
+ HTTP/1.1 200 OK\r\n
+ Content-Type: text/html\r\n
+ \r\n
+ Welcome:
\r\n
+ '''
"""
# 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"])
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"])
def parse_request(request):
"""
Given the content of an HTTP request, returns the path of that request.
- This server only handles GET requests, so this method shall raise a
- NotImplementedError if the method of the request is not GET.
+ This server only handles GET requests, so this method shall raise a
+ NotImplementedError if the method of the request is not GET.
"""
-
+ method, path, version = request.split("\r\n")[0].split(" ")
+ if method != "GET":
+ raise NotImplementedError
# TODO: implement parse_request
- return ""
+ return path
def response_path(path):
"""
This method should return appropriate content and a mime type.
- If the requested path is a directory, then the content should be a
- plain-text listing of the contents with mimetype `text/plain`.
+ If the requested path is a directory, then the content should be a
+ plain-text listing of the contents with mimetype `text/plain`.
- If the path is a file, it should return the contents of that file
- and its correct mimetype.
+ If the path is a file, it should return the contents of that file
+ and its correct mimetype.
- If the path does not map to a real location, it should raise an
- exception that the server can catch to return a 404 response.
+ If the path does not map to a real location, it should raise an
+ exception that the server can catch to return a 404 response.
- Ex:
+ Ex:
response_path('/a_web_page.html') -> (b"North Carolina...",
b"text/html")
@@ -85,9 +93,27 @@ 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"
+
+
+
+ file_path = os.path.join(os.getcwd(), 'webroot', path.strip('/'))
+
+ # If the path indicates a directory:
+ if os.path.isdir(file_path):
+ content = "\n".join(os.listdir(file_path)).encode('utf8')
+ mime_type = b"text/plain"
+ return content, mime_type
+
+ # If the path indicates a file:
+ elif os.path.exists(file_path):
+ mime_type = mimetypes.guess_type(file_path)[0].encode('utf8')
+ with open(file_path, "br") as f:
+ content = f.read()
+ return content, mime_type
+
+ # If the path does not indicate an existing directory or file:
+ else:
+ raise NameError
return content, mime_type
@@ -114,30 +140,37 @@ def server(log_buffer=sys.stderr):
if '\r\n\r\n' in request:
break
-
+
print("Request received:\n{}\n\n".format(request))
+ try:
+ path = parse_request(request)
+
+ # TODO: Use parse_request to retrieve the path from the 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: 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.
+ content, mimetype = response_path(path)
+ except NotImplementedError:
+ response = response_method_not_allowed()
+ conn.sendall(response)
+ except NameError:
+ response = response_not_found()
+ conn.sendall(response)
- # 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(content, mimetype)
conn.sendall(response)
except:
traceback.print_exc()
finally:
- conn.close()
+ conn.close()
except KeyboardInterrupt:
sock.close()