Skip to content

Commit a590a5c

Browse files
committed
working on ESP8266
1 parent 3b2d8e7 commit a590a5c

File tree

2 files changed

+55
-13
lines changed

2 files changed

+55
-13
lines changed

gurgleapps_webserver.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import ujson as json
77
from response import Response
88
from request import Request
9+
import gc
10+
import os
911

1012

1113
class GurgleAppsWebserver:
@@ -25,7 +27,6 @@ def __init__(self, wifi_ssid, wifi_password, port=80, timeout=20, doc_root="/www
2527
self.wlan.active(True)
2628
# connect to the access point with the ssid and password
2729
self.wlan.connect(self.wifi_ssid, self.wifi_password)
28-
2930
self.html = """<!DOCTYPE html>
3031
<html>
3132
<head> <title>GurgleApps.com Webserver</title> </head>
@@ -78,6 +79,7 @@ def add_function_route(self, route, function):
7879
self.function_routes.append({"route": route, "function": function})
7980

8081
async def serve_request(self, reader, writer):
82+
gc.collect()
8183
try:
8284
url = ""
8385
method = ""
@@ -87,18 +89,27 @@ async def serve_request(self, reader, writer):
8789
post_data = None
8890
while True:
8991
line = await reader.readline()
92+
#print("line: "+str(line))
9093
line = line.decode('utf-8').strip()
9194
if line == "":
9295
break
9396
headers.append(line)
94-
request_raw = str("\r".join(headers))
97+
request_raw = str("\r\n".join(headers))
9598
print(request_raw)
9699
request_pattern = re.compile(r"(GET|POST)\s+([^\s]+)\s+HTTP")
97100
match = request_pattern.search(request_raw)
98101
if match:
99102
method = match.group(1)
100103
url = match.group(2)
101104
print(method, url)
105+
else: # regex didn't match, try splitting the request line
106+
request_parts = request_raw.split(" ")
107+
if len(request_parts) > 1:
108+
method = request_parts[0]
109+
url = request_parts[1]
110+
print(method, url)
111+
else:
112+
print("no match")
102113
# extract content length for POST requests
103114
if method == "POST":
104115
content_length_pattern = re.compile(r"Content-Length:\s+(\d+)")
@@ -123,15 +134,14 @@ async def serve_request(self, reader, writer):
123134
await route_function(request, response, *params)
124135
return
125136
# perhaps it is a file
126-
file = self.get_file(self.doc_root + url)
127-
if self.log_level > 2:
128-
print("file: "+str(file))
129-
if file:
130-
print("file found so serving it")
137+
file_path = self.doc_root + url
138+
if self.log_level > 0:
139+
print("file_path: "+str(file_path))
140+
if uos.stat(file_path)[6] > 0:
131141
content_type = self.get_content_type(url)
132142
if self.log_level > 1:
133143
print("content_type: "+str(content_type))
134-
await response.send(file, 200, content_type)
144+
await response.send_file(file_path, content_type=content_type)
135145
return
136146
print("file not found")
137147
await response.send(self.html % "page not found "+url, status_code=404)
@@ -158,17 +168,21 @@ def get_file(self, filename):
158168
return False
159169

160170
def get_path_components(self, path):
171+
print("get_path_components: "+path)
161172
return tuple(filter(None, path.split('/')))
162173

163174
def match_route(self, path_components):
164175
for route in self.function_routes:
165176
route_pattern = list(filter(None, route["route"].split("/")))
166-
# print("route_pattern: "+str(route_pattern))
177+
if self.log_level > 1:
178+
print("route_pattern: "+str(route_pattern))
167179
if len(route_pattern) != len(path_components):
168180
continue
169181
match = True
170182
params = []
171183
for idx, pattern_component in enumerate(route_pattern):
184+
if self.log_level > 2:
185+
print("pattern_component: "+str(pattern_component))
172186
if pattern_component.startswith('<') and pattern_component.endswith('>'):
173187
param_value = path_components[idx]
174188
params.append(param_value)

response.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1-
# response.py
1+
import os
22

33
class Response:
44
def __init__(self, writer):
55
self.writer = writer
66

7-
async def send(self, body, status_code = 200, content_type = "text/html"):
8-
self.writer.write(f'HTTP/1.0 {status_code}\r\nContent-type: {content_type}\r\n\r\n')
7+
async def send_headers(self, status_code=200, content_type="text/html", content_length=None):
8+
headers = f'HTTP/1.0 {status_code}\r\nContent-type: {content_type}\r\n'
9+
if content_length is not None:
10+
headers += f'Content-Length: {content_length}\r\n'
11+
headers += '\r\n'
12+
self.writer.write(headers)
13+
await self.writer.drain()
14+
15+
async def send(self, body, status_code=200, content_type="text/html"):
16+
await self.send_headers(status_code, content_type)
917
self.writer.write(body)
1018
await self.writer.drain()
1119
await self.writer.wait_closed()
@@ -14,4 +22,24 @@ async def send_html(self, body, status_code=200):
1422
await self.send(body, status_code, content_type='text/html')
1523

1624
async def send_json(self, body, status_code=200):
17-
await self.send(body, status_code, content_type='application/json')
25+
await self.send(body, status_code, content_type='application/json')
26+
27+
async def send_file(self, file_path, status_code=200, content_type="text/html"):
28+
try:
29+
file_size = os.stat(file_path)[6]
30+
await self.send_headers(status_code, content_type, content_length=file_size)
31+
32+
chunk_size = 1024 # Adjust the chunk size as needed
33+
with open(file_path, "rb") as f:
34+
while True:
35+
chunk = f.read(chunk_size)
36+
if not chunk:
37+
break
38+
self.writer.write(chunk)
39+
await self.writer.drain()
40+
41+
await self.writer.wait_closed()
42+
43+
except Exception as e:
44+
print("Error sending file:", e)
45+
await self.send('', status_code=404)

0 commit comments

Comments
 (0)