-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathESP8266WebServer.py
115 lines (103 loc) · 3.35 KB
/
ESP8266WebServer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# A simple HTTP server that only accept GET request
# It adopt the programming style of ESP8266WebServer
# library in ESP8266 Arduino Core
import network
import machine
import socket
import uselect
import os
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Use for checking a new client connection
poller = uselect.poll()
# Dict for registed handlers of all paths
handlers = {}
# The path to the web documents on MicroPython filesystem
docPath = "/defaultWWW"
# Function to start http server
def begin(port):
global server, poller
server.bind(('0.0.0.0', port))
# MicroPython v1.10-8 has a bug, workaround here:
server.listen(2)
#server.listen(1) # v1.9.4 should use this.
# Register for checking new client connection
poller.register(server, uselect.POLLIN)
def close():
poller.unregister(server)
server.close()
# Check for new client connection and process the request
def handleClient():
global server, poller
# Note:don't call poll() with 0, that would randomly cause
# reset with "Fatal exception 28(LoadProhibitedCause)" message
res = poller.poll(1)
if res: # There's a new client connection
(socket, sockaddr) = server.accept()
handle(socket)
socket.close()
# Respong error meesage to client
def err(socket, code, message):
socket.write("HTTP/1.1 " + code + " " + message + "\r\n\r\n")
socket.write("<h1>" + message + "</h1>")
# Response succesful message to client
def ok(socket, code, msg):
socket.write("HTTP/1.1 " + code + " OK\r\n\r\n")
socket.write(msg)
# Processing new GET request
def handle(socket):
global docPath, handlers
currLine = str(socket.readline(), 'utf-8')
request = currLine.split(" ")
if len(request) != 3: # Discarded if it's a bad header
return
(method, url, version) = request
if "?" in url: # Check if there's query string?
(path, query) = url.split("?", 2)
else:
(path, query) = (url, "")
args = {}
if query: # Parsing the querying string
argPairs = query.split("&")
for argPair in argPairs:
arg = argPair.split("=")
args[arg[0]] = arg[1]
while True: # Read until blank line after header
header = socket.readline()
if header == b"":
return
if header == b"\r\n":
break
# Check for supported HTTP version
if version != "HTTP/1.0\r\n" and version != "HTTP/1.1\r\n":
err(socket, "505", "Version Not Supported")
elif method == "GET": # Only accept GET request
if path.find(docPath) == 0: # Check for path to any document
try:
os.stat(path) # Check for file existence
# Response header first
socket.write("HTTP/1.1 200 OK\r\n\r\n")
# Response the file content
f = open(path, "rb")
while True:
data = f.read(64)
if (data == b""):
break
socket.write(data)
return
except: # Can't find the file specified in path
err(socket, "404", "Not Found")
elif path in handlers: # Check for registered path
handlers[path](socket, args)
else:
err(socket, "400", "Bad Request")
else:
err(socket, "501", "Not Implemented")
# Register handler for processing request fo specified path
def onPath(path, handler):
global handlers
handlers[path] = handler
# Set the path to documents' directory
def setDocPath(path):
global docPath
docPath = path