diff --git a/http_server.py b/http_server.py index 58d7386..64d2ef1 100644 --- a/http_server.py +++ b/http_server.py @@ -2,6 +2,10 @@ 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 @@ -18,22 +22,30 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):

Welcome:

\r\n ''' """ + return b"\r\n".join([ + b"HTTP/1.1 200 OK", + b"Content-Type: " + mimetype, + b"", + body, + ]) - # TODO: Implement response_ok - return b"" 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 Method Not Found", + b"", + b"Not found!", + ]) def parse_request(request): @@ -43,9 +55,11 @@ def parse_request(request): 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 + return path - # TODO: implement parse_request - return "" def response_path(path): """ @@ -74,20 +88,22 @@ def response_path(path): response_path('/a_page_that_doesnt_exist.html') -> Raises a NameError """ + home_path = os.getcwd() + "/webroot" + path + + # URI is a directory, then return plain-text listing of the contents and mime_type + if os.path.isdir(home_path): + content = ('\r\n, '.join(os.listdir(home_path))).encode('utf8') + mime_type = b"text/plain" - # TODO: Raise a NameError if the requested content is not present - # under webroot. + # URI is a file, then return contents of file and mime_type + elif os.path.isfile(home_path): + with open(home_path, 'rb') as file: + content = file.read() + mime_type = mimetypes.guess_type(path)[0].encode('utf8') - # 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`. - - content = b"not implemented" - mime_type = b"not implemented" + # Raise a NameError if the requested content is not present under webroot. + else: + raise NameError return content, mime_type @@ -115,24 +131,27 @@ 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: + # Retrieve path from request + path = parse_request(request) + + # Use response_path to retrieve the content and mimetype, based on request path + content, mime_type = response_path(path) + + # Use content and mimetype from response_path to build a response_ok + response = response_ok(content, mime_type) + + # If NotImplementedError, then response is method_not_allowed response + except NotImplementedError: + response = response_method_not_allowed() # Error 405 + + # If NameError, then response is not_found response + except NameError: + response = response_not_found() # Error 404 + + # Send response conn.sendall(response) except: traceback.print_exc() @@ -142,6 +161,7 @@ def server(log_buffer=sys.stderr): except KeyboardInterrupt: sock.close() return + except: traceback.print_exc() @@ -149,5 +169,3 @@ def server(log_buffer=sys.stderr): if __name__ == '__main__': server() sys.exit(0) - -