123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- 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
|