77from response import Response
88from request import Request
99
10+
1011class GurgleAppsWebserver :
1112
12- def __init__ (self , wifi_ssid , wifi_password , port = 80 , timeout = 20 , doc_root = "/www" ):
13+ def __init__ (self , wifi_ssid , wifi_password , port = 80 , timeout = 20 , doc_root = "/www" , log_level = 0 ):
1314 print ("GurgleApps.com Webserver" )
1415 self .port = port
1516 self .timeout = timeout
1617 self .wifi_ssid = wifi_ssid
1718 self .wifi_password = wifi_password
1819 self .doc_root = doc_root
19- self .function_routes = []
20+ self .function_routes = []
21+ self .log_level = log_level
2022 # wifi client in station mode so we can connect to an access point
2123 self .wlan = network .WLAN (network .STA_IF )
2224 # activate the interface
@@ -50,21 +52,21 @@ def __init__(self, wifi_ssid, wifi_password, port=80, timeout=20, doc_root="/www
5052 print ('point your browser to http://' , status [0 ])
5153 try :
5254 pass
53- #asyncio.run(self.start_server())
55+ # asyncio.run(self.start_server())
5456 except OSError as e :
5557 print (e )
5658 finally :
5759 asyncio .new_event_loop ()
5860 print ("exit constructor" )
5961
6062 async def start_server (self ):
61- asyncio .create_task (asyncio .start_server (self .serve_request , "0.0.0.0" , 80 ))
62- while self .serving :
63- await asyncio .sleep (1 )
64-
63+ asyncio .create_task (asyncio .start_server (
64+ self .serve_request , "0.0.0.0" , 80 ))
65+ while self .serving :
66+ await asyncio .sleep (1 )
67+
6568 def add_function_route (self , route , function ):
66- self .function_routes .append ({"route" :route , "function" :function })
67-
69+ self .function_routes .append ({"route" : route , "function" : function })
6870
6971 async def serve_request (self , reader , writer ):
7072 try :
@@ -107,16 +109,20 @@ async def serve_request(self, reader, writer):
107109 print ("path_components: " + str (path_components ))
108110 route_function , params = self .match_route (path_components )
109111 if route_function :
110- print ("calling function: " + str (route_function )+ " with params: " + str (params ))
112+ print ("calling function: " + str (route_function ) +
113+ " with params: " + str (params ))
111114 await route_function (request , response , * params )
112115 return
113116 # perhaps it is a file
114117 file = self .get_file (self .doc_root + url )
115- print ("file: " + str (file ))
118+ if self .log_level > 2 :
119+ print ("file: " + str (file ))
116120 if file :
117121 print ("file found so serving it" )
118- print (file )
119- await response .send (file )
122+ content_type = self .get_content_type (url )
123+ if self .log_level > 1 :
124+ print ("content_type: " + str (content_type ))
125+ await response .send (file , 200 , content_type )
120126 return
121127 print ("file not found" )
122128 await response .send (self .html % "page not found " + url , status_code = 404 )
@@ -127,7 +133,7 @@ async def serve_request(self, reader, writer):
127133
128134 def get_file (self , filename ):
129135 print ("getFile: " + filename )
130- try :
136+ try :
131137 # Check if the file exists
132138 if uos .stat (filename )[6 ] > 0 :
133139 # Open the file in read mode
@@ -141,20 +147,21 @@ def get_file(self, filename):
141147 # print the error
142148 print (e )
143149 return False
144-
150+
145151 def get_path_components (self , path ):
146152 return tuple (filter (None , path .split ('/' )))
147-
153+
148154 def match_route (self , path_components ):
149155 for route in self .function_routes :
150156 route_pattern = list (filter (None , route ["route" ].split ("/" )))
151- #print("route_pattern: "+str(route_pattern))
157+ # print("route_pattern: "+str(route_pattern))
152158 if len (route_pattern ) != len (path_components ):
153159 continue
154160 match = True
155161 params = []
156162 for idx , pattern_component in enumerate (route_pattern ):
157- print ("pattern_component: " + pattern_component + " path_component: " + path_components [idx ])
163+ print ("pattern_component: " + pattern_component +
164+ " path_component: " + path_components [idx ])
158165 if pattern_component .startswith ('<' ) and pattern_component .endswith ('>' ):
159166 param_value = path_components [idx ]
160167 params .append (param_value )
@@ -166,5 +173,23 @@ def match_route(self, path_components):
166173 return route ["function" ], params
167174 return None , []
168175
176+ def get_file_extension (self , file_path ):
177+ file_parts = file_path .split ('.' )
178+ if len (file_parts ) > 1 :
179+ return file_parts [- 1 ]
180+ return ''
169181
170182
183+ def get_content_type (self ,file_path ):
184+ extension = self .get_file_extension (file_path )
185+ content_type_map = {
186+ 'html' : 'text/html' ,
187+ 'css' : 'text/css' ,
188+ 'js' : 'application/javascript' ,
189+ 'jpg' : 'image/jpeg' ,
190+ 'jpeg' : 'image/jpeg' ,
191+ 'png' : 'image/png' ,
192+ 'gif' : 'image/gif' ,
193+ 'ico' : 'image/x-icon'
194+ }
195+ return content_type_map .get (extension , 'text/plain' )
0 commit comments