Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions src/lua_resty_netacea.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@ local function serveCaptchaFailOpen(body, options)
return true
end

local function readRequestBody()
ngx.req.read_body()

local body = ngx.req.get_body_data()
if body ~= nil then
return body
end

local body_file = ngx.req.get_body_file()
if not body_file then
return nil
end

local file, err = io.open(body_file, "rb")
if not file then
ngx.log(ngx.WARN, "NETACEA CAPTCHA - unable to read request body file: ", err)
return nil
end

local data = file:read("*a")
file:close()

return data
end

function _N:new(options)
local n = {}
setmetatable(n, self)
Expand Down Expand Up @@ -257,8 +282,7 @@ end
function _N:handleCaptcha()
self:handleSession()

ngx.req.read_body()
local captcha_data = ngx.req.get_body_data()
local captcha_data = readRequestBody()
local protector_result = self.protectorClient:validateCaptcha(captcha_data)
ngx.ctx.NetaceaState.protector_result = protector_result
ngx.ctx.NetaceaState.grace_period = -1000
Expand Down
67 changes: 67 additions & 0 deletions test/lua_resty_netacea_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ insulate("lua_resty_netacea", function()
req = {
read_body = spy.new(function() end),
get_body_data = spy.new(function() return "captcha-response" end),
get_body_file = spy.new(function() return nil end),
set_header = spy.new(function() end)
},
DEBUG = 7,
Expand Down Expand Up @@ -926,6 +927,72 @@ insulate("lua_resty_netacea", function()
assert.spy(ngx_mock.print).was.called_with("Captcha OK")
assert.spy(ngx_mock.exit).was.called_with(200)
end)

it("should read captcha request bodies from the temporary file when needed", function()
local body_file = os.tmpname()
local file = assert(io.open(body_file, "wb"))
file:write("captcha-from-file")
file:close()

ngx_mock.req.get_body_data = spy.new(function()
return nil
end)
ngx_mock.req.get_body_file = spy.new(function()
return body_file
end)

local captured_body
protector_client_instance.validateCaptcha = spy.new(function(_, body)
captured_body = body
return {
match = "1",
mitigate = "1",
captcha = "2",
exit_status = 200,
captcha_cookie = nil,
response = {
body = "Captcha OK"
}
}
end)

local netacea = new_mitigation_enabled_netacea()

netacea:handleCaptcha()

assert.are.equal("captcha-from-file", captured_body)
os.remove(body_file)
end)

it("should return nil captcha body when the body file cannot be read", function()
ngx_mock.req.get_body_data = spy.new(function()
return nil
end)
ngx_mock.req.get_body_file = spy.new(function()
return "/tmp/definitely-not-a-real-body-file"
end)

local captured_body
protector_client_instance.validateCaptcha = spy.new(function(_, body)
captured_body = body
return {
match = "1",
mitigate = "1",
captcha = "2",
exit_status = 200,
captcha_cookie = nil,
response = {
body = "Captcha OK"
}
}
end)

local netacea = new_mitigation_enabled_netacea()

netacea:handleCaptcha()

assert.is_nil(captured_body)
end)
end)
end)
end)