-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttp_server.lua
More file actions
164 lines (139 loc) · 4.58 KB
/
http_server.lua
File metadata and controls
164 lines (139 loc) · 4.58 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
-- создание един. подключения к MySQL.
package.cpath = package.cpath .. ";C:/lua/clibs/?.dll"
local socket = require("socket")
mysql = require "luasql.mysql"
local env = mysql.mysql()
local conn = env:connect('test','root','','localhost',3306)
cursor,errorString = conn:execute('SET NAMES utf8')
-- чтение заголовка от User для нахождения строки с параметрами.
local function read_param_string(client)
local first_header_line, err = client:receive("*l")
if first_header_line == nil then return nil, err end
local pattern = "GET%s(%S+)%sHTTP"
local match = string.match(first_header_line, pattern)
match = string.gsub(tostring(match), "/?%?", "")
:gsub("^/", "")
:gsub("%%(%x%x)", function(hex) return string.char(tonumber(hex, 16)) end)
if match ~= '' then
return match
else
return nil, err
end
end
-- основная функция для формирования таблицы.
local function ViewSelect(conn)
-- заголовок таблицы.
local line_table = "<tr>"
cursor,errorString = conn:execute([[SHOW COLUMNS FROM myarttable]])
row = cursor:fetch ({}, "a")
while row do
line_table = line_table .. string.format("<td>%s</td>", row.Field)
row = cursor:fetch (row, "a")
end
cursor:close()
line_table = line_table .. "</tr>"
-- строки таблицы.
cursor,errorString = conn:execute([[SELECT * FROM myarttable WHERE id>14 ORDER BY id DESC]])
row = cursor:fetch ({}, "a")
while row do
line_table = line_table .. string.format("<tr><td> %s </td><td> %s </td><td> %s </td><td> %s </td></tr>", row.id, row.text, row.description, row.keywords)
row = cursor:fetch (row, "a")
end
cursor:close()
return line_table
end
-- получение версии БД из MySQL.
local function ViewVer(conn)
print("BD VERSION.\n")
cursor,errorString = conn:execute([[SELECT VERSION() AS ver]])
row = cursor:fetch ({}, "a")
local line_ver = row.ver
cursor:close()
return line_ver
end
-- формирование HTML для отправки User.
local function thread_func()
-- построчное чтение файла из шаблона.
local file = "select.html"
local line_all = ''
for line in io.lines(file) do
if not string.find(line, "@tr") and not string.find(line, "@ver") then
line_all = line_all .. line
end
if string.find(line, "@tr") then
line_all = line_all .. ViewSelect(conn)
end
if string.find(line, "@ver") then
line_all = line_all .. ViewVer(conn)
end
end
coroutine.yield(line_all)
end
function urldecode(s)
s = s:gsub('+', ' '):gsub('%%(%x%x)', function(h)
return string.char(tonumber(h, 16))
end)
return s
end
function parseurl(s)
s = s:match('%s+(.+)')
local ans = {}
for k,v in s:gmatch('([^&=?]-)=([^&=?]+)' ) do
ans[ k ] = urldecode(v)
end
return ans
end
-- парсинг строки с параметрами.
function parse_param_string(paramString)
print("Given params: " .. paramString)
local col1, col2, col3
for pair in paramString:gmatch("([^&]+)") do
local key, value = pair:match("([^=]+)=(.*)")
if key == "col1" then
col1 = value
elseif key == "col2" then
col2 = value
elseif key == "col3" then
col3 = value
end
end
print("First value: " .. tostring(col1))
print("Second value: " .. tostring(col2))
print("Third value: " .. tostring(col3))
return col1, col2, col3
end
-- добавление строки в таблицу.
function insert_values(col1, col2, col3)
local sql = string.format("INSERT INTO myarttable (text, description, keywords) VALUES ('%s', '%s', '%s')", col1, col2, col3)
cursor,errorString = conn:execute(sql)
if errorString == nil then
print("Insertion successful")
end
end
-- создание web-сервера.
local server = assert(socket.tcp())
server:setoption("reuseaddr", true)
server:settimeout(0)
assert(server:bind("0.0.0.0", 8880))
server:listen(0)
print("Listening on http://localhost:8880/ ...")
while true do
-- ожидание подключений...
local client, err = server:accept()
if client then
local param_string = read_param_string(client)
if param_string ~= nil then
local col1, col2, col3 = parse_param_string(param_string)
if col1 ~= nil and col2 ~= nil and col3 ~= nil then
insert_values(col1, col2, col3)
end
end
local status, data_html = coroutine.resume(coroutine.create(thread_func))
client:send('HTTP/1.1 200 OK; Content-Type: text/html; charset=utf-8 \n\r\n\r' .. data_html)
client:close()
print("Sending to user... ok.\n")
end
end
-- закрытие подключения к БД.
conn:close()
env:close()