summaryrefslogtreecommitdiffstats
path: root/reg-tests/lua/txn_get_priv.lua
blob: dd5623c15ff82552bba8766fd6e26808aec40644 (plain)
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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)