-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathprocessing.lua
More file actions
148 lines (139 loc) · 4.26 KB
/
Copy pathprocessing.lua
File metadata and controls
148 lines (139 loc) · 4.26 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
--[[
NAME: HTTP request processing
DESCRIPTION:
Processing of HTTP request including Basic HTTP Authentication.
Public function populates current HTML template with current state of pins,
creates web page, ads HTTP headers and sends response to the client.
If there is not basic authentication present in the request from a browser,
the function invokes login dialog in the browser.
CREDENTIALS:
Author: Libor Gabaj
GitHub: https://github.com/mrkale/NodeMCU-WifiDoubleSwitch.git
--]]
--Update input HTML template string by replacing placeholders with current values
local function updateTemplate(templateString)
--Project params
require("s2eta")
templateString=templateString:gsub("\${version}", cfg_init.version)
templateString=templateString:gsub("\${uptime}", s2eta.eta(cfg_init.uptime))
templateString=templateString:gsub("\${startDate}", cfg_init.startDate)
templateString=templateString:gsub("\${currDate}", cfg_init.currDate)
s2eta, package.loaded["s2eta"]=nil,nil
collectgarbage()
--Template constants
for key, value in pairs(cfg_tmpl_cons)
do
templateString=templateString:gsub("\${"..key.."}", value)
end
--Pins state
for i, params in ipairs(cfg_pins)
do
for key, value in pairs(cfg_tmpl_states[params.status])
do
templateString = templateString:gsub("\${"..key.."_"..i.."}", value)
end
end
return templateString
end
--Create HTML page from template
local function getPage(tmpl)
if not file.open(tmpl) then return '' end
local chunk, content = '', ''
repeat
if chunk
then
content = content .. chunk
chunk = file.read(cfg_init.limitFile)
end
collectgarbage()
until not chunk or (#content + #chunk > cfg_init.limitString)
file.close()
collectgarbage()
--Update template placeholders
return updateTemplate(content)
end
--Send final HTML page to the client (browser) in chunks
local function sendPage(client, page)
local chunk
local function sender(client)
if #page > 0
then
chunk = page:sub(1, cfg_init.limitSend)
page = page:sub(cfg_init.limitSend + 1, #page)
client:send(chunk, sender)
else
client:close()
end
end
sender(client)
collectgarbage()
end
--Create HTTP status line for input code
local function getHttpStatus(code)
local httpCodes = {
[200] = "OK",
[400] = "Bad Request",
[401] = "Authorization Required\r\nWWW-Authenticate: Basic realm=\""..cfg_header_cons.header_realm.."\"",
[501] = "Not implemented",
}
local header = httpCodes[code]
if header
then
header = "HTTP/1.1 "..code.." "..header.."\r\n"
else
header = getHttpHeaders(501)
end
return header
end
--Create HTTP headers
local function getHttpHeaders(code, bodyLength)
local header = getHttpStatus(code)
.. "Content-Type: text/html; charset=UTF-8\r\n"
.. "Server: " .. cfg_header_cons.header_server .. "\r\n"
.. "Date: " .. cfg_init.httpDate .. "\r\n"
if bodyLength
then
header = header .. "Content-Length: " .. tostring(bodyLength) .. "\r\n"
end
return header
end
--Process HTTP request
return function (client, request)
local page
--Dummy requests
if request:match("GET /favicon.ico HTTP") then return end
--Check authorization
local auth = request:match("Authorization: Basic ([A-Za-z0-9+/=]+)")
if (auth == nil or auth ~= cfg_credentials.httpSECRET)
then
page = getPage(cfg_init.tmpl_err)
page = getHttpHeaders(401, #page).."\r\n"..page
sendPage(client, page)
return
end
local req_pin, req_state
local req_pinstate = request:match("GET /%?" .. cfg_tmpl_cons.reqvar_pin .. "=(%d+) HTTP/([1-9]+.[0-9]+)")
--Process pins
if req_pinstate == nil
then
if cfg_init.debug then print("No pin state") end
else
if cfg_init.debug then print("Pin state="..req_pinstate) end
while #req_pinstate > 0
do
req_pin = req_pinstate:sub(1, 1) + 0
req_state = req_pinstate:sub(2, 2) + 0
local params = cfg_pins[req_pin]
if params ~= nil
then
params.status = req_state
gpio.write(params.pin, params.status)
end
req_pinstate = req_pinstate:sub(3, #req_pinstate)
end
end
--Prepare HTML page and send it
page = getPage(cfg_init.tmpl_page)
page = getHttpHeaders(200, #page).."\r\n"..page
sendPage(client, page)
end