From ac29ab1f9d1cb20a69026c4cdf6bb11b9c49fcbd Mon Sep 17 00:00:00 2001 From: Kate Koehn Date: Sun, 21 Apr 2019 13:04:43 -0700 Subject: [PATCH] submitting http-server homework --- http_server.py | 82 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/http_server.py b/http_server.py index 58d7386..c366ee5 100644 --- a/http_server.py +++ b/http_server.py @@ -1,6 +1,8 @@ import socket import sys import traceback +import mimetypes +import os def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): """ @@ -18,22 +20,30 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):

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", + 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"404 body!", + ]) def parse_request(request): @@ -43,9 +53,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, protocol = request.split("\r\n")[0].split(" ") + if method != "GET": + raise NotImplementedError("This server only handles GET requests.") - # TODO: implement parse_request - return "" + return path def response_path(path): """ @@ -74,6 +86,23 @@ def response_path(path): response_path('/a_page_that_doesnt_exist.html') -> Raises a NameError """ + home_dir = os.path.abspath("webroot") + location = os.path.join(home_dir, path[1:]) + + if os.path.isdir(location): + mime_type = mimetypes.types_map['.txt'].encode() + content = os.listdir(location) + str_content = str(content).encode() + return str_content, mime_type + + if os.path.isfile(location): + with open(location, 'rb') as f: + content = f.read() + mime_type = mimetypes.guess_type(location, strict=True)[0].encode() + return content, mime_type + + #print(response_not_found(), "Error encountered while visiting " + path) + raise NameError # TODO: Raise a NameError if the requested content is not present # under webroot. @@ -85,11 +114,7 @@ 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 def server(log_buffer=sys.stderr): @@ -114,30 +139,37 @@ 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. + print("Request received:\n{}\n\n".format(request)) + try: + path = parse_request(request) + print("Sending response", file=log_buffer) + content, mime_type = response_path(path) + response = response_ok(body=content, mimetype=mime_type) # TODO: Use response_path to retrieve the content and the mimetype, # based on the request path. + except NotImplementedError: + response = response_method_not_allowed() + #content, mime_type = resolve_uri(url) + except NameError: + response = response_not_found() # 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 + # 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" - ) - conn.sendall(response) + except: + traceback.print_exc() + finally: + conn.sendall(response) + conn.close() + except: traceback.print_exc() - finally: - conn.close() except KeyboardInterrupt: sock.close()