diff --git a/http_server.py b/http_server.py index 58d7386..1369ef0 100644 --- a/http_server.py +++ b/http_server.py @@ -1,39 +1,45 @@ +# from os import path import socket import sys +import os import traceback +import mimetypes + + +root_dir = '/'.join([os.getcwd(), 'webroot']) 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 - ''' - """ + """returns a basic HTTP response""" # 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"\r\n".join([ + b"HTTP/1.1 404 Not Found", + b"", + b"You can't do that on this server!", + ]) def parse_request(request): @@ -45,7 +51,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): """ @@ -59,20 +71,6 @@ def response_path(path): 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: - response_path('/a_web_page.html') -> (b"

North Carolina...", - b"text/html") - - response_path('/images/sample_1.png') - -> (b"A12BCF...", # contents of sample_1.png - b"image/png") - - response_path('/') -> (b"images/, a_web_page.html, make_type.py,...", - b"text/plain") - - response_path('/a_page_that_doesnt_exist.html') -> Raises a NameError - """ # TODO: Raise a NameError if the requested content is not present @@ -85,11 +83,21 @@ 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" - return content, mime_type + mime_type = "text/plain" + + if path == "/": + content = "\n".join([x for x in os.listdir(root_dir)]).encode() + elif not "." in path: + content = "\n".join([x for x in os.listdir(root_dir + path)]).encode() + else: + try: + with open("".join([root_dir, path]), 'rb') as f: + content = f.read() + mime_type = mimetypes.guess_type(path)[0] + except FileNotFoundError: + raise NameError + return content, mime_type.encode() def server(log_buffer=sys.stderr): @@ -112,27 +120,39 @@ def server(log_buffer=sys.stderr): data = conn.recv(1024) request += data.decode('utf8') - if '\r\n\r\n' in request: + if len(data) < 1024: + break + if b'\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: + path = parse_request(request) + + # TODO: Use response_path to retrieve the content and the mimetype, + # based on the request path. + 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. + except NotImplementedError: + response = response_method_not_allowed() + else: + try: + body, mimetype = response_path(path) + except NameError: + response = response_not_found() + else: + response = response_ok(body=body, mimetype=mimetype) conn.sendall(response) except: traceback.print_exc()