181 lines
4.8 KiB
Lua
181 lines
4.8 KiB
Lua
Luacurl = {}
|
|
Luacurl.__index = Luacurl
|
|
setmetatable(Luacurl, {
|
|
__call = function (cls, ...)
|
|
return cls.new(...)
|
|
end,
|
|
})
|
|
function Luacurl.new(server, port, ssl)
|
|
local self = setmetatable({}, Luacurl)
|
|
self.sockconnected = false
|
|
self.server = server
|
|
self.port = port
|
|
self.ssl = ssl
|
|
self.cookies = {}
|
|
return self
|
|
end
|
|
|
|
function Luacurl:get(method,url,headers,data)
|
|
core.Info("MAKING SOCKET")
|
|
if self.sockconnected == false then
|
|
self.sock = core.tcp()
|
|
if self.ssl then
|
|
local r = self.sock:connect_ssl(self.server,self.port)
|
|
else
|
|
local r = self.sock:connect(self.server,self.port)
|
|
end
|
|
self.sockconnected = true
|
|
end
|
|
core.Info("SOCKET MADE")
|
|
local request = method.." "..url.." HTTP/1.1"
|
|
if data ~= nil then
|
|
request = request .. "\r\nContent-Length: "..string.len(data)
|
|
end
|
|
if headers ~= null then
|
|
for h,v in pairs(headers) do
|
|
request = request .. "\r\n"..h..": "..v
|
|
end
|
|
end
|
|
cookstring = ""
|
|
for cook,cookval in pairs(self.cookies) do
|
|
cookstring = cookstring .. cook.."="..cookval.."; "
|
|
end
|
|
if string.len(cookstring) > 0 then
|
|
request = request .. "\r\nCookie: "..cookstring
|
|
end
|
|
|
|
request = request .. "\r\n\r\n"
|
|
if data and string.len(data) > 0 then
|
|
request = request .. data
|
|
end
|
|
--print(request)
|
|
core.Info("SENDING REQUEST")
|
|
self.sock:send(request)
|
|
|
|
-- core.Info("PROCESSING RESPONSE")
|
|
return processhttpresponse(self.sock)
|
|
end
|
|
|
|
function processhttpresponse(socket)
|
|
local res = {}
|
|
core.Info("1")
|
|
res.status = socket:receive("*l")
|
|
core.Info("2")
|
|
|
|
if res.status == nil then
|
|
core.Info(" processhttpresponse RECEIVING status: NIL")
|
|
return res
|
|
end
|
|
core.Info(" processhttpresponse RECEIVING status:"..res.status)
|
|
res.headers = {}
|
|
res.headerslist = {}
|
|
repeat
|
|
core.Info("3")
|
|
local header = socket:receive("*l")
|
|
if header == nil then
|
|
return "error"
|
|
end
|
|
local valuestart = header:find(":")
|
|
if valuestart ~= nil then
|
|
local head = header:sub(1,valuestart-1)
|
|
local value = header:sub(valuestart+2)
|
|
table.insert(res.headerslist, {head,value})
|
|
res.headers[head] = value
|
|
end
|
|
until header == ""
|
|
local bodydone = false
|
|
if res.headers["Connection"] ~= nil and res.headers["Connection"] == "close" then
|
|
-- core.Info("luacurl processresponse with connection:close")
|
|
res.body = ""
|
|
repeat
|
|
core.Info("4")
|
|
local d = socket:receive("*a")
|
|
if d ~= nil then
|
|
res.body = res.body .. d
|
|
end
|
|
until d == nil or d == 0
|
|
bodydone = true
|
|
end
|
|
if bodydone == false and res.headers["Content-Length"] ~= nil then
|
|
res.contentlength = tonumber(res.headers["Content-Length"])
|
|
if res.contentlength == nil then
|
|
core.Warning("res.contentlength ~NIL = "..res.headers["Content-Length"])
|
|
end
|
|
-- core.Info("luacur, contentlength="..res.contentlength)
|
|
res.body = ""
|
|
repeat
|
|
local d = socket:receive(res.contentlength)
|
|
if d == nil then
|
|
-- core.Info("luacurl, ERROR?: received NIL, expecting "..res.contentlength.." bytes only got "..string.len(res.body).." sofar")
|
|
return
|
|
else
|
|
res.body = res.body..d
|
|
-- core.Info("luacurl, COMPLETE?: expecting "..res.contentlength.." bytes, got "..string.len(res.body))
|
|
if string.len(res.body) >= res.contentlength then
|
|
-- core.Info("luacurl, COMPLETE?: expecting "..res.contentlength.." bytes, got "..string.len(res.body))
|
|
break
|
|
end
|
|
end
|
|
-- core.Info("processhttpresponse, Loopy, get more body data! to receive complete contentlenght")
|
|
until false
|
|
end
|
|
if res.headers["Transfer-Encoding"] ~= nil and res.headers["Transfer-Encoding"] == "chunked" then
|
|
local chunksize = 0
|
|
res.contentlength = 0
|
|
res.body = ""
|
|
repeat
|
|
core.Info("5")
|
|
local chunksizestr = socket:receive("*l")
|
|
if chunksizestr == nil then
|
|
break
|
|
end
|
|
chunksize = tonumber("0x"..chunksizestr)
|
|
if chunksize ~= nil then
|
|
res.contentlength = res.contentlength + chunksize
|
|
if chunksize ~= 0 then
|
|
local chunk = socket:receive(chunksize)
|
|
res.body = res.body .. chunk
|
|
chunksizestr = socket:receive("*l")
|
|
if chunksizestr ~= "" then
|
|
return "ERROR Chunk-end expected."
|
|
end
|
|
end
|
|
else
|
|
break
|
|
end
|
|
until false
|
|
end
|
|
core.Info("6")
|
|
return res
|
|
end
|
|
|
|
function Luacurl:close()
|
|
if self.sockconnected == true then
|
|
self.sock:close()
|
|
self.sockconnected = false
|
|
end
|
|
end
|
|
|
|
function print_r_string(object)
|
|
local res = ""
|
|
print_r(object,false,function(x) res = res .. x end)
|
|
return res
|
|
end
|
|
|
|
core.register_service("fakeserv", "http", function(applet)
|
|
core.Info("APPLET START")
|
|
local mc = Luacurl("127.0.0.1",8443, true)
|
|
local headers = {}
|
|
local body = ""
|
|
core.Info("APPLET GET")
|
|
local res = mc:get("GET", "/", headers, body)
|
|
core.Info("APPLET GET done")
|
|
local response = print_r_string(res)
|
|
applet:add_header("Server", "haproxy/webstats")
|
|
applet:add_header("Content-Length", string.len(response))
|
|
applet:add_header("Content-Type", "text/html")
|
|
applet:start_response()
|
|
applet:send(response)
|
|
core.Info("APPLET DONE")
|
|
end)
|