forked from cloudwu/skynet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimpleweb.lua
122 lines (113 loc) · 3.28 KB
/
simpleweb.lua
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
local skynet = require "skynet"
local socket = require "skynet.socket"
local httpd = require "http.httpd"
local sockethelper = require "http.sockethelper"
local urllib = require "http.url"
local table = table
local string = string
local mode, protocol = ...
protocol = protocol or "http"
if mode == "agent" then
local function response(id, write, ...)
local ok, err = httpd.write_response(write, ...)
if not ok then
-- if err == sockethelper.socket_error , that means socket closed.
skynet.error(string.format("fd = %d, %s", id, err))
end
end
local SSLCTX_SERVER = nil
local function gen_interface(protocol, fd)
if protocol == "http" then
return {
init = nil,
close = nil,
read = sockethelper.readfunc(fd),
write = sockethelper.writefunc(fd),
}
elseif protocol == "https" then
local tls = require "http.tlshelper"
if not SSLCTX_SERVER then
SSLCTX_SERVER = tls.newctx()
-- gen cert and key
-- openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-cert.pem
local certfile = skynet.getenv("certfile") or "./server-cert.pem"
local keyfile = skynet.getenv("keyfile") or "./server-key.pem"
print(certfile, keyfile)
SSLCTX_SERVER:set_cert(certfile, keyfile)
end
local tls_ctx = tls.newtls("server", SSLCTX_SERVER)
return {
init = tls.init_responsefunc(fd, tls_ctx),
close = tls.closefunc(tls_ctx),
read = tls.readfunc(fd, tls_ctx),
write = tls.writefunc(fd, tls_ctx),
}
else
error(string.format("Invalid protocol: %s", protocol))
end
end
skynet.start(function()
skynet.dispatch("lua", function (_,_,id)
socket.start(id)
local interface = gen_interface(protocol, id)
if interface.init then
interface.init()
end
-- limit request body size to 8192 (you can pass nil to unlimit)
local code, url, method, header, body = httpd.read_request(interface.read, 8192)
if code then
if code ~= 200 then
response(id, interface.write, code)
else
local tmp = {}
if header.host then
table.insert(tmp, string.format("host: %s", header.host))
end
local path, query = urllib.parse(url)
table.insert(tmp, string.format("path: %s", path))
if query then
local q = urllib.parse_query(query)
for k, v in pairs(q) do
table.insert(tmp, string.format("query: %s= %s", k,v))
end
end
table.insert(tmp, "-----header----")
for k,v in pairs(header) do
table.insert(tmp, string.format("%s = %s",k,v))
end
table.insert(tmp, "-----body----\n" .. body)
response(id, interface.write, code, table.concat(tmp,"\n"))
end
else
if url == sockethelper.socket_error then
skynet.error("socket closed")
else
skynet.error(url)
end
end
socket.close(id)
if interface.close then
interface.close()
end
end)
end)
else
skynet.start(function()
local agent = {}
local protocol = "http"
for i= 1, 20 do
agent[i] = skynet.newservice(SERVICE_NAME, "agent", protocol)
end
local balance = 1
local id = socket.listen("0.0.0.0", 8001)
skynet.error(string.format("Listen web port 8001 protocol:%s", protocol))
socket.start(id , function(id, addr)
skynet.error(string.format("%s connected, pass it to agent :%08x", addr, agent[balance]))
skynet.send(agent[balance], "lua", id)
balance = balance + 1
if balance > #agent then
balance = 1
end
end)
end)
end