From 2bdd602c281361affe6feaa4825efe6583654ba8 Mon Sep 17 00:00:00 2001 From: stevetwalker <29964517+stevetwalker@users.noreply.github.com> Date: Sun, 26 Apr 2020 20:26:28 -0700 Subject: [PATCH] Initial commit --- http_server.py | 88 +++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/http_server.py b/http_server.py index 58d7386..158fedd 100644 --- a/http_server.py +++ b/http_server.py @@ -1,6 +1,8 @@ import socket import sys import traceback +import os +import mimetypes def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): """ @@ -19,22 +21,30 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"): ''' """ - # 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"There's no place for a method like that on a server like this.", + ]) 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"Looks like you're barking up the wrong tree, my friend.", + ]) def parse_request(request): """ @@ -44,8 +54,14 @@ def parse_request(request): NotImplementedError if the method of the request is not GET. """ - # TODO: implement parse_request - return "" + # The path is always in the first line of an HTTP request. + # The first line is structured as {method} {path} {version} (e.g. GET /library HTTP/1.1). + method, path, version = request.split("\r\n")[0].split(" ") + + if method != "GET": + raise NotImplementedError + + return path def response_path(path): """ @@ -75,19 +91,24 @@ def response_path(path): """ - # TODO: Raise a NameError if the requested content is not present - # under webroot. + # os.path.abspath('.') returns the path of the current directory + path = os.path.abspath('.') + '/webroot' + path - # 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" + # If the path leads to a file, serve it up + if os.path.isfile(path): + filetype = path[path.rfind("."):] + mime_type = mimetypes.types_map[filetype].encode() + with open(path, 'rb') as file: + content = file.read() + + # If the path leads to a directory, list its contents + elif os.path.isdir(path): + content = ", ".join(os.listdir(path)).encode() + mime_type = b"text/plain" + + # If the path doesn't exist, raise a NameError + else: + raise NameError return content, mime_type @@ -115,23 +136,18 @@ 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. + try: + path = parse_request(request) + body, mime_type = response_path(path) + response = response_ok(body, 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() - # 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" - ) + except NameError: + response = response_not_found() conn.sendall(response) except: @@ -149,5 +165,3 @@ def server(log_buffer=sys.stderr): if __name__ == '__main__': server() sys.exit(0) - -