Fix. read callback hangup if it returns wrong value
parent
05272ea096
commit
1062805482
|
@ -17,6 +17,7 @@ before_install:
|
|||
- bash .travis/setup_lua.sh
|
||||
- sudo luarocks install lunitx
|
||||
- sudo pip install cpp-coveralls
|
||||
- sudo luarocks install dkjson
|
||||
|
||||
install:
|
||||
- sudo luarocks make rockspecs/lcurl-scm-0.rockspec CFLAGS="-O2 -fPIC -ftest-coverage -fprofile-arcs" LIBFLAG="-shared --coverage"
|
||||
|
|
35
src/lceasy.c
35
src/lceasy.c
|
@ -696,15 +696,38 @@ static size_t lcurl_read_callback(lua_State *L,
|
|||
|
||||
n = lcurl_util_push_cb(L, rd);
|
||||
lua_pushinteger(L, ret);
|
||||
if(lua_pcall(L, n, LUA_MULTRET, 0)) return CURL_READFUNC_ABORT;
|
||||
|
||||
if(lua_isnoneornil(L, top + 1)){
|
||||
if(lua_gettop(L) <= (top + 1))return 0;
|
||||
if(lua_pcall(L, n, LUA_MULTRET, 0)){
|
||||
assert(lua_gettop(L) >= top);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top+1);
|
||||
return CURL_READFUNC_ABORT;
|
||||
}
|
||||
data = lua_tolstring(L, -1, &data_size);
|
||||
if(!data) return CURL_READFUNC_ABORT;
|
||||
|
||||
if(lua_gettop(L) == top){
|
||||
return CURL_READFUNC_ABORT;
|
||||
}
|
||||
|
||||
assert(lua_gettop(L) >= top);
|
||||
|
||||
if(lua_type(L, top + 1) != LUA_TSTRING){
|
||||
if(lua_isnil(L, top + 1)){
|
||||
if(lua_gettop(L) == (top+1)) lua_settop(L, top);
|
||||
}
|
||||
else{
|
||||
if(lua_type(L, top + 1) == LUA_TNUMBER){
|
||||
size_t ret = lua_tonumber(L, top + 1);
|
||||
if(ret == (size_t)CURL_READFUNC_PAUSE){
|
||||
lua_settop(L, top);
|
||||
return CURL_READFUNC_PAUSE;
|
||||
}
|
||||
}
|
||||
lua_settop(L, top);
|
||||
}
|
||||
return CURL_READFUNC_ABORT;
|
||||
}
|
||||
|
||||
data = lua_tolstring(L, top + 1, &data_size);
|
||||
assert(data);
|
||||
if(data_size > ret){
|
||||
data_size = ret;
|
||||
rbuffer->ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||
|
|
|
@ -5,6 +5,7 @@ local skip = lunit.skip or function() end
|
|||
|
||||
local curl = require "lcurl"
|
||||
local scurl = require "lcurl.safe"
|
||||
local json = require "dkjson"
|
||||
local url = "http://example.com"
|
||||
local fname = "./test.download"
|
||||
|
||||
|
@ -17,7 +18,9 @@ local function gc_collect()
|
|||
collectgarbage("collect")
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'write_callback' do
|
||||
local ENABLE = true
|
||||
|
||||
local _ENV = TEST_CASE'write_callback' if ENABLE then
|
||||
|
||||
local c, f
|
||||
|
||||
|
@ -84,6 +87,9 @@ function test_reset_write_callback()
|
|||
assert_equal(c, c:setopt_writefunction(f))
|
||||
assert_equal(c, c:setopt_writefunction(f.write, f))
|
||||
assert_equal(c, c:setopt_writefunction(print))
|
||||
assert_error(function()c:setopt_writefunction()end)
|
||||
assert_error(function()c:setopt_writefunction(nil)end)
|
||||
assert_error(function()c:setopt_writefunction(nil, f)end)
|
||||
end
|
||||
|
||||
function test_write_pass_01()
|
||||
|
@ -113,10 +119,9 @@ function test_write_pass_03()
|
|||
assert_equal(c, c:perform())
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'progress_callback' do
|
||||
local _ENV = TEST_CASE'progress_callback' if ENABLE then
|
||||
|
||||
local c
|
||||
|
||||
|
@ -225,7 +230,224 @@ end
|
|||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'escape' do
|
||||
local _ENV = TEST_CASE'header_callback' if ENABLE then
|
||||
|
||||
local c, f
|
||||
local function dummy() end
|
||||
|
||||
function teardown()
|
||||
if c then c:close() end
|
||||
f, c = nil
|
||||
end
|
||||
|
||||
function test_header_abort_01()
|
||||
c = assert(scurl.easy{
|
||||
url = url;
|
||||
writefunction = dummy,
|
||||
headerfunction = function(str) return #str - 1 end;
|
||||
})
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal(curl.error(curl.ERROR_EASY, curl.E_WRITE_ERROR), e)
|
||||
end
|
||||
|
||||
function test_header_abort_02()
|
||||
c = assert(scurl.easy{
|
||||
url = url;
|
||||
writefunction = dummy,
|
||||
headerfunction = function(str) return false end;
|
||||
})
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal(curl.error(curl.ERROR_EASY, curl.E_WRITE_ERROR), e)
|
||||
end
|
||||
|
||||
function test_header_abort_03()
|
||||
c = assert(scurl.easy{
|
||||
url = url;
|
||||
writefunction = dummy,
|
||||
headerfunction = function(str) return nil, "WRITEERROR" end;
|
||||
})
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal("WRITEERROR", e)
|
||||
end
|
||||
|
||||
function test_header_abort_04()
|
||||
c = assert(scurl.easy{
|
||||
url = url;
|
||||
writefunction = dummy,
|
||||
headerfunction = function(str) return nil end;
|
||||
})
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal(curl.error(curl.ERROR_EASY, curl.E_WRITE_ERROR), e)
|
||||
end
|
||||
|
||||
function test_reset_header_callback()
|
||||
f = {header = function() end}
|
||||
c = assert(curl.easy{url = url})
|
||||
assert_equal(c, c:setopt_headerfunction(f))
|
||||
assert_equal(c, c:setopt_headerfunction(f.header, f))
|
||||
assert_equal(c, c:setopt_headerfunction(print))
|
||||
assert_error(function()c:setopt_headerfunction()end)
|
||||
assert_error(function()c:setopt_headerfunction(nil)end)
|
||||
assert_error(function()c:setopt_headerfunction(nil, f)end)
|
||||
end
|
||||
|
||||
function test_header_pass_01()
|
||||
c = assert(curl.easy{
|
||||
url = url;
|
||||
writefunction = dummy,
|
||||
headerfunction = function(s) return #s end
|
||||
})
|
||||
|
||||
assert_equal(c, c:perform())
|
||||
end
|
||||
|
||||
function test_header_pass_02()
|
||||
c = assert(curl.easy{
|
||||
url = url;
|
||||
writefunction = dummy,
|
||||
headerfunction = function() return end
|
||||
})
|
||||
|
||||
assert_equal(c, c:perform())
|
||||
end
|
||||
|
||||
function test_header_pass_03()
|
||||
c = assert(curl.easy{
|
||||
url = url;
|
||||
writefunction = dummy,
|
||||
headerfunction = function() return true end
|
||||
})
|
||||
|
||||
assert_equal(c, c:perform())
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'reader_callback' if ENABLE then
|
||||
|
||||
local url = "http://httpbin.org/post"
|
||||
|
||||
local c, f, t
|
||||
|
||||
local function get_bin_by(str,n)
|
||||
local pos = 1 - n
|
||||
return function()
|
||||
pos = pos + n
|
||||
return (str:sub(pos,pos+n-1))
|
||||
end
|
||||
end
|
||||
|
||||
local function strem(ch, n, m)
|
||||
return n, get_bin_by( (ch):rep(n), m)
|
||||
end
|
||||
|
||||
local function json_data()
|
||||
return json.decode(table.concat(t))
|
||||
end
|
||||
|
||||
function setup()
|
||||
t = {}
|
||||
f = assert(scurl.form())
|
||||
c = assert(scurl.easy{
|
||||
url = url,
|
||||
})
|
||||
assert_equal(c, c:setopt_writefunction(table.insert, t))
|
||||
end
|
||||
|
||||
function teardown()
|
||||
if f then f:free() end
|
||||
if c then c:close() end
|
||||
t, f, c = nil
|
||||
end
|
||||
|
||||
function test()
|
||||
assert_equal(f, f:add_stream('SSSSS', strem('X', 128, 13)))
|
||||
assert_equal(c, c:setopt_httppost(f))
|
||||
assert_equal(c, c:perform())
|
||||
assert_equal(200, c:getinfo_response_code())
|
||||
local data = assert_table(json_data())
|
||||
assert_table(data.form)
|
||||
assert_equal(('X'):rep(128), data.form.SSSSS)
|
||||
end
|
||||
|
||||
function test_abort_01()
|
||||
assert_equal(f, f:add_stream('SSSSS', 128, function() end))
|
||||
assert_equal(c, c:setopt_httppost(f))
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal(curl.error(curl.ERROR_EASY, curl.E_ABORTED_BY_CALLBACK), e)
|
||||
end
|
||||
|
||||
function test_abort_02()
|
||||
assert_equal(f, f:add_stream('SSSSS', 128, function() return nil, "READERROR" end))
|
||||
assert_equal(c, c:setopt_httppost(f))
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal("READERROR", e)
|
||||
end
|
||||
|
||||
function test_abort_03()
|
||||
assert_equal(f, f:add_stream('SSSSS', 128, function() return 1 end))
|
||||
assert_equal(c, c:setopt_httppost(f))
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal(curl.error(curl.ERROR_EASY, curl.E_ABORTED_BY_CALLBACK), e)
|
||||
end
|
||||
|
||||
function test_abort_04()
|
||||
assert_equal(f, f:add_stream('SSSSS', 128, function() return true end))
|
||||
assert_equal(c, c:setopt_httppost(f))
|
||||
|
||||
local _, e = assert_nil(c:perform())
|
||||
assert_equal(curl.error(curl.ERROR_EASY, curl.E_ABORTED_BY_CALLBACK), e)
|
||||
end
|
||||
|
||||
function test_abort_04()
|
||||
assert_equal(f, f:add_stream('SSSSS', 128, function() error("READERROR") end))
|
||||
assert_equal(c, c:setopt_httppost(f))
|
||||
|
||||
assert_error_match("READERROR", function() c:perform() end)
|
||||
end
|
||||
|
||||
function test_pause()
|
||||
local counter = 0
|
||||
assert_equal(f, f:add_stream('SSSSS', 128, function()
|
||||
if counter == 0 then
|
||||
counter = counter + 1
|
||||
return curl.READFUNC_PAUSE
|
||||
end
|
||||
if counter == 1 then
|
||||
counter = counter + 1
|
||||
return ('X'):rep(128)
|
||||
end
|
||||
return ''
|
||||
end))
|
||||
|
||||
assert_equal(c, c:setopt_progressfunction(function()
|
||||
if counter == 1 then
|
||||
c:pause(curl.PAUSE_CONT)
|
||||
end
|
||||
end))
|
||||
|
||||
assert_equal(c, c:setopt_noprogress(false))
|
||||
|
||||
assert_equal(c, c:setopt_httppost(f))
|
||||
|
||||
assert_equal(c, c:perform())
|
||||
assert_equal(200, c:getinfo_response_code())
|
||||
local data = assert_table(json_data())
|
||||
assert_table(data.form)
|
||||
assert_equal(('X'):rep(128), data.form.SSSSS)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'escape' if ENABLE then
|
||||
|
||||
local c
|
||||
|
||||
|
@ -244,7 +466,7 @@ end
|
|||
|
||||
end
|
||||
|
||||
local _ENV = TEST_CASE'setopt_form' do
|
||||
local _ENV = TEST_CASE'setopt_form' if ENABLE then
|
||||
|
||||
local c
|
||||
|
||||
|
|
Loading…
Reference in New Issue