11import socket
22import sys
33import traceback
4+ import os
5+ import mimetypes
46
57def response_ok (body = b"This is a minimal response" , mimetype = b"text/plain" ):
68 """
@@ -19,22 +21,30 @@ def response_ok(body=b"This is a minimal response", mimetype=b"text/plain"):
1921 '''
2022 """
2123
22- # TODO: Implement response_ok
23- return b""
24+ return b"\r \n " .join ([
25+ b"HTTP/1.1 200 OK" ,
26+ b"Content-Type: " + mimetype ,
27+ b"" ,
28+ body ,
29+ ])
2430
2531def response_method_not_allowed ():
2632 """Returns a 405 Method Not Allowed response"""
2733
28- # TODO: Implement response_method_not_allowed
29- return b""
30-
34+ return b"\r \n " .join ([
35+ b"HTTP/1.1 405 Method Not Allowed" ,
36+ b"" ,
37+ b"There's no place for a method like that on a server like this." ,
38+ ])
3139
3240def response_not_found ():
3341 """Returns a 404 Not Found response"""
3442
35- # TODO: Implement response_not_found
36- return b""
37-
43+ return b"\r \n " .join ([
44+ b"HTTP/1.1 404 Not Found" ,
45+ b"" ,
46+ b"Looks like you're barking up the wrong tree, my friend." ,
47+ ])
3848
3949def parse_request (request ):
4050 """
@@ -44,8 +54,14 @@ def parse_request(request):
4454 NotImplementedError if the method of the request is not GET.
4555 """
4656
47- # TODO: implement parse_request
48- return ""
57+ # The path is always in the first line of an HTTP request.
58+ # The first line is structured as {method} {path} {version} (e.g. GET /library HTTP/1.1).
59+ method , path , version = request .split ("\r \n " )[0 ].split (" " )
60+
61+ if method != "GET" :
62+ raise NotImplementedError
63+
64+ return path
4965
5066def response_path (path ):
5167 """
@@ -75,19 +91,24 @@ def response_path(path):
7591
7692 """
7793
78- # TODO: Raise a NameError if the requested content is not present
79- # under webroot.
94+ # os.path.abspath('.') returns the path of the current directory
95+ path = os . path . abspath ( '.' ) + '/webroot' + path
8096
81- # TODO: Fill in the appropriate content and mime_type give the path.
82- # See the assignment guidelines for help on "mapping mime-types", though
83- # you might need to create a special case for handling make_time.py
84- #
85- # If the path is "make_time.py", then you may OPTIONALLY return the
86- # result of executing `make_time.py`. But you need only return the
87- # CONTENTS of `make_time.py`.
88-
89- content = b"not implemented"
90- mime_type = b"not implemented"
97+ # If the path leads to a file, serve it up
98+ if os .path .isfile (path ):
99+ filetype = path [path .rfind ("." ):]
100+ mime_type = mimetypes .types_map [filetype ].encode ()
101+ with open (path , 'rb' ) as file :
102+ content = file .read ()
103+
104+ # If the path leads to a directory, list its contents
105+ elif os .path .isdir (path ):
106+ content = ", " .join (os .listdir (path )).encode ()
107+ mime_type = b"text/plain"
108+
109+ # If the path doesn't exist, raise a NameError
110+ else :
111+ raise NameError
91112
92113 return content , mime_type
93114
@@ -115,23 +136,18 @@ def server(log_buffer=sys.stderr):
115136 if '\r \n \r \n ' in request :
116137 break
117138
118-
119139 print ("Request received:\n {}\n \n " .format (request ))
120140
121- # TODO: Use parse_request to retrieve the path from the request.
141+ try :
142+ path = parse_request (request )
143+ body , mime_type = response_path (path )
144+ response = response_ok (body , mime_type )
122145
123- # TODO: Use response_path to retrieve the content and the mimetype,
124- # based on the request path.
146+ except NotImplementedError :
147+ response = response_method_not_allowed ()
125148
126- # TODO; If parse_request raised a NotImplementedError, then let
127- # response be a method_not_allowed response. If response_path raised
128- # a NameError, then let response be a not_found response. Else,
129- # use the content and mimetype from response_path to build a
130- # response_ok.
131- response = response_ok (
132- body = b"Welcome to my web server" ,
133- mimetype = b"text/plain"
134- )
149+ except NameError :
150+ response = response_not_found ()
135151
136152 conn .sendall (response )
137153 except :
@@ -149,5 +165,3 @@ def server(log_buffer=sys.stderr):
149165if __name__ == '__main__' :
150166 server ()
151167 sys .exit (0 )
152-
153-
0 commit comments