commit
316cf79070
@ -4,10 +4,8 @@ description='Lua binding to libcurl'
|
||||
format='discount'
|
||||
backtick_references=false
|
||||
file={
|
||||
'../src/lua/cURL.lua',
|
||||
'../src/lua/cURL/safe.lua',
|
||||
'../src/lua/cURL/utils.lua',
|
||||
'../src/lua/cURL/impl/cURL.lua',
|
||||
'./curl.ldoc',
|
||||
'./lcurl.ldoc',
|
||||
}
|
||||
dir='html'
|
||||
readme='../README.md'
|
||||
@ -24,7 +22,15 @@ examples = {
|
||||
'../examples/lcurl/post.lua',
|
||||
'../examples/lcurl/post_stream.lua',
|
||||
'../examples/lcurl/share.lua',
|
||||
'../examples/cURLv3',
|
||||
|
||||
'../examples/cURLv2/file.lua',
|
||||
'../examples/cURLv2/browser.lua',
|
||||
'../examples/cURLv2/rss.lua',
|
||||
'../examples/cURLv2/multi.lua',
|
||||
'../examples/cURLv2/post_stream.lua',
|
||||
'../examples/cURLv3/post_json.lua',
|
||||
'../examples/cURLv3/post_form.lua',
|
||||
|
||||
'../examples/cURLv3/pop3.lua',
|
||||
'../examples/cURLv3/file.lua',
|
||||
'../examples/cURLv3/rss.lua',
|
||||
@ -32,17 +38,4 @@ examples = {
|
||||
'../examples/cURLv3/multi.lua',
|
||||
'../examples/cURLv3/post_form.lua',
|
||||
'../examples/cURLv3/multi2.lua',
|
||||
'../examples/cURLv2',
|
||||
'../examples/cURLv2/file.lua',
|
||||
'../examples/cURLv2/browser.lua',
|
||||
'../examples/cURLv2/rss.lua',
|
||||
'../examples/cURLv2/multi.lua',
|
||||
'../examples/cURLv2/post_stream.lua',
|
||||
'../test/test_easy.lua',
|
||||
'../test/run.lua',
|
||||
'../test/test_form.lua',
|
||||
'../test/test_safe.lua',
|
||||
'../test/test_curl.lua',
|
||||
'../test/.luacov',
|
||||
'../test/test_pause02.c.lua',
|
||||
}
|
||||
|
146
doc/lcurl.ldoc
146
doc/lcurl.ldoc
@ -54,6 +54,23 @@ function version() end
|
||||
-- if proto.HTTP then ... -- libcurl support http protocol
|
||||
function version_info() end
|
||||
|
||||
--- File description table.
|
||||
--
|
||||
-- Representation for `struct curl_fileinfo`
|
||||
--
|
||||
-- @table curl_fileinfo
|
||||
--
|
||||
-- @tfield string filename
|
||||
-- @tfield integer filetype
|
||||
-- @tfield integer time
|
||||
-- @tfield integer perm
|
||||
-- @tfield integer uid
|
||||
-- @tfield integer gid
|
||||
-- @tfield integer size
|
||||
-- @tfield integer hardlinks
|
||||
-- @tfield integer flags
|
||||
-- @tfield table strings can have this string fields: `time`, `perm` , `user` , `group`, `target`
|
||||
|
||||
end
|
||||
|
||||
--- HTTP multipart/formdata object
|
||||
@ -367,6 +384,135 @@ function setopt_progressfunction() end
|
||||
--
|
||||
function setopt_progressfunction() end
|
||||
|
||||
--- Set seek callback function.
|
||||
--
|
||||
-- A callback accepting two or three parameters.
|
||||
-- The first is the seek context if any, the second is the `origin` value
|
||||
-- same as in file.seek function from io library. Can be (`cur`, `set` and `end`).
|
||||
-- The third parameter is offset or position in input stream.
|
||||
-- If stream can not be seeking and need stop current transfer operation
|
||||
-- function have to raise Lua error or returns `nil` and error message.
|
||||
-- To indicate success function have to return any truthy value
|
||||
-- In other case Function must return `true` or `1` or nothing to continue operation.
|
||||
-- False value indicate that while the seek failed, libcurl is free to work
|
||||
-- around the problem if possible.
|
||||
--
|
||||
-- !!! NOTE !!! This is differents form libcurl API by swapping parameters in callback.
|
||||
-- It done to be compatiable with Lua io library.
|
||||
--
|
||||
-- @tparam function seek
|
||||
-- @param[opt] context seek context
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_seekfunction() end
|
||||
|
||||
--- Set seek callback function.
|
||||
--
|
||||
-- This call same as easy:setopt_seekfunction(stream.seek, seek)
|
||||
--
|
||||
-- @tparam object stream
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_seekfunction() end
|
||||
|
||||
--- Set debug callback function.
|
||||
--
|
||||
-- A callback accepting two or three parameters.
|
||||
-- The first is the debug context if any, the second is the `data_type` value
|
||||
-- which represent what kinde of data is passed. This value can be one of
|
||||
-- constant `INFO_TEXT`, `INFO_HEADER_IN`, `INFO_HEADER_OUT`, `INFO_DATA_IN`,
|
||||
-- `INFO_DATA_OUT`, `INFO_SSL_DATA_IN`, `INFO_SSL_DATA_OUT`.
|
||||
-- The third parameter is data itself.
|
||||
-- Any errors and returning values from this callback are ignored.
|
||||
--
|
||||
-- @tparam function debug
|
||||
-- @param[opt] context debug context
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_debugfunction() end
|
||||
|
||||
--- Set debug callback function.
|
||||
--
|
||||
-- This call same as easy:setopt_debugfunction(debug.debug, debug)
|
||||
--
|
||||
-- @tparam object debug
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_debugfunction() end
|
||||
|
||||
--- Set match callback function.
|
||||
--
|
||||
-- A callback accepting two or three parameters.
|
||||
-- The first is the match context if any, the second is the pattern string,
|
||||
-- the third is the string to match to pattern.
|
||||
-- Function must return truthy value to indicate that string match to pattern.
|
||||
-- If function raise error or return nil and error message then it indicate
|
||||
-- that curl should interrupt current transfer operation.
|
||||
-- False value indicate that strind does not match to pattern
|
||||
--
|
||||
-- @tparam function match
|
||||
-- @param[opt] context match context
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_fnmatch_function() end
|
||||
|
||||
--- Set match callback function.
|
||||
--
|
||||
-- This call same as easy:setopt_fnmatch_function(match.match, match)
|
||||
--
|
||||
-- @tparam object match
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_fnmatch_function() end
|
||||
|
||||
|
||||
--- Set chunk begin function.
|
||||
--
|
||||
-- A callback accepting two or three parameters.
|
||||
-- The first is the chunk context if any, the second is the @{curl_fileinfo} table.
|
||||
-- The third parameter contains number of chunks remaining per the transfer.
|
||||
-- Function must return truthy value or nothing to indicate that transfer can begin.
|
||||
-- If function raise error or return nil and error message then it indicate
|
||||
-- that curl should interrupt current transfer operation.
|
||||
-- False value indicate that curl should skip this chunk.
|
||||
--
|
||||
-- @tparam function chunk_bgn
|
||||
-- @param[opt] context chunk context
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_chunk_bgn_function() end
|
||||
|
||||
--- Set chunk begin function.
|
||||
--
|
||||
-- This call same as easy:setopt_chunk_bgn_function(context.chunk_bgn, context)
|
||||
--
|
||||
-- @tparam object context
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_chunk_bgn_function() end
|
||||
|
||||
--- Set chunk end function.
|
||||
--
|
||||
-- A callback accepting zero or one parameter.
|
||||
-- The only parameter is the chunk context if any.
|
||||
-- Function must return truthy value or nothing to indicate that transfer can continue
|
||||
-- otherwise it indicate that curl should interrupt current transfer operation.
|
||||
--
|
||||
-- @tparam function chunk_end
|
||||
-- @param[opt] context chunk context
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_chunk_end_function() end
|
||||
|
||||
--- Set chunk begin function.
|
||||
--
|
||||
-- This call same as easy:setopt_chunk_end_function(context.chunk_end, context)
|
||||
--
|
||||
-- @tparam object context
|
||||
-- @return[1] self
|
||||
--
|
||||
function setopt_chunk_end_function() end
|
||||
|
||||
--- Set HTTP multipart/formdata.
|
||||
--
|
||||
-- Caller does not have to save data.
|
||||
|
1
lakefile
1
lakefile
@ -14,6 +14,7 @@ cURL = c.shared{'lcurl',
|
||||
defines = DEFINES,
|
||||
dynamic = DYNAMIC,
|
||||
strip = true,
|
||||
cflags = IF(not MSVC, {'-Wno-unused-local-typedefs'})
|
||||
}
|
||||
|
||||
target('build', cURL)
|
||||
|
392
src/lceasy.c
392
src/lceasy.c
@ -79,6 +79,11 @@ int lcurl_easy_create(lua_State *L, int error_mode){
|
||||
p->rd.cb_ref = p->rd.ud_ref = LUA_NOREF;
|
||||
p->hd.cb_ref = p->hd.ud_ref = LUA_NOREF;
|
||||
p->pr.cb_ref = p->pr.ud_ref = LUA_NOREF;
|
||||
p->seek.cb_ref = p->seek.ud_ref = LUA_NOREF;
|
||||
p->debug.cb_ref = p->debug.ud_ref = LUA_NOREF;
|
||||
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
|
||||
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
|
||||
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
|
||||
p->rbuffer.ref = LUA_NOREF;
|
||||
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
||||
p->lists[i] = LUA_NOREF;
|
||||
@ -140,6 +145,16 @@ static int lcurl_easy_cleanup(lua_State *L){
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->rd.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->pr.cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->pr.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->seek.cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->seek.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->debug.cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->debug.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->match.cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->match.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_bgn.cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_bgn.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->chunk_end.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.cb_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->hd.ud_ref);
|
||||
luaL_unref(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
|
||||
@ -148,6 +163,11 @@ static int lcurl_easy_cleanup(lua_State *L){
|
||||
p->rd.cb_ref = p->rd.ud_ref = LUA_NOREF;
|
||||
p->hd.cb_ref = p->hd.ud_ref = LUA_NOREF;
|
||||
p->pr.cb_ref = p->pr.ud_ref = LUA_NOREF;
|
||||
p->seek.cb_ref = p->seek.ud_ref = LUA_NOREF;
|
||||
p->debug.cb_ref = p->debug.ud_ref = LUA_NOREF;
|
||||
p->match.cb_ref = p->match.ud_ref = LUA_NOREF;
|
||||
p->chunk_bgn.cb_ref = p->chunk_bgn.ud_ref = LUA_NOREF;
|
||||
p->chunk_end.cb_ref = p->chunk_end.ud_ref = LUA_NOREF;
|
||||
p->rbuffer.ref = LUA_NOREF;
|
||||
|
||||
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
||||
@ -613,6 +633,74 @@ static int lcurl_easy_unset_POSTFIELDS(lua_State *L){
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcurl_easy_unset_SEEKFUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
|
||||
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_SEEKFUNCTION, NULL);
|
||||
if(code != CURLE_OK){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
curl_easy_setopt(p->curl, CURLOPT_SEEKDATA, NULL);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcurl_easy_unset_DEBUGFUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
|
||||
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_DEBUGFUNCTION, NULL);
|
||||
if(code != CURLE_OK){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
curl_easy_setopt(p->curl, CURLOPT_DEBUGDATA, NULL);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
|
||||
static int lcurl_easy_unset_FNMATCH_FUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
|
||||
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_FNMATCH_FUNCTION, NULL);
|
||||
if(code != CURLE_OK){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
curl_easy_setopt(p->curl, CURLOPT_FNMATCH_DATA, NULL);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcurl_easy_unset_CHUNK_BGN_FUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
|
||||
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_CHUNK_BGN_FUNCTION, NULL);
|
||||
if(code != CURLE_OK){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
// curl_easy_setopt(p->curl, CURLOPT_CHUNK_DATA, NULL);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
static int lcurl_easy_unset_CHUNK_END_FUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
|
||||
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_CHUNK_END_FUNCTION, NULL);
|
||||
if(code != CURLE_OK){
|
||||
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||
}
|
||||
// curl_easy_setopt(p->curl, CURLOPT_CHUNK_DATA, NULL);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if LCURL_CURL_VER_GE(7,46,0)
|
||||
|
||||
static int lcurl_easy_unset_STREAM_DEPENDS(lua_State *L){
|
||||
@ -1009,6 +1097,243 @@ static int lcurl_easy_set_PROGRESSFUNCTION(lua_State *L){
|
||||
|
||||
//}
|
||||
|
||||
//{ Seek
|
||||
|
||||
static int lcurl_seek_callback(void *arg, curl_off_t offset, int origin){
|
||||
lcurl_easy_t *p = arg;
|
||||
lua_State *L = p->L;
|
||||
int ret = CURL_SEEKFUNC_OK;
|
||||
int top = lua_gettop(L);
|
||||
int n = lcurl_util_push_cb(L, &p->seek);
|
||||
|
||||
assert(NULL != p->L);
|
||||
|
||||
if (SEEK_SET == origin) lua_pushliteral(L, "set");
|
||||
else if (SEEK_CUR == origin) lua_pushliteral(L, "cur");
|
||||
else if (SEEK_END == origin) lua_pushliteral(L, "end");
|
||||
else lua_pushinteger(L, origin);
|
||||
lutil_pushint64(L, offset);
|
||||
|
||||
if (lua_pcall(L, n+1, LUA_MULTRET, 0)) {
|
||||
assert(lua_gettop(L) >= top);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
}
|
||||
|
||||
if(lua_gettop(L) > top){
|
||||
if(lua_isnil(L, top + 1) && (!lua_isnoneornil(L, top + 2))){
|
||||
lua_settop(L, top + 2);
|
||||
lua_remove(L, top + 1);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_SEEKFUNC_FAIL;
|
||||
}
|
||||
ret = lua_toboolean(L, top + 1) ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK;
|
||||
}
|
||||
|
||||
lua_settop(L, top);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcurl_easy_set_SEEKFUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
return lcurl_easy_set_callback(L, p, &p->seek,
|
||||
CURLOPT_SEEKFUNCTION, CURLOPT_SEEKDATA,
|
||||
"seek", lcurl_seek_callback
|
||||
);
|
||||
}
|
||||
|
||||
//}
|
||||
|
||||
//{ Debug
|
||||
|
||||
static int lcurl_debug_callback(CURL *handle, curl_infotype type, char *data, size_t size, void *arg){
|
||||
lcurl_easy_t *p = arg;
|
||||
lua_State *L = p->L;
|
||||
int top = lua_gettop(L);
|
||||
int n = lcurl_util_push_cb(L, &p->debug);
|
||||
|
||||
assert(NULL != p->L);
|
||||
assert(handle == p->curl);
|
||||
|
||||
lua_pushinteger(L, type);
|
||||
lua_pushlstring(L, data, size);
|
||||
|
||||
// just ignore all errors from Lua callback
|
||||
lua_pcall(L, n + 1, LUA_MULTRET, 0);
|
||||
lua_settop(L, top);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcurl_easy_set_DEBUGFUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
return lcurl_easy_set_callback(L, p, &p->debug,
|
||||
CURLOPT_DEBUGFUNCTION, CURLOPT_DEBUGDATA,
|
||||
"debug", lcurl_debug_callback
|
||||
);
|
||||
}
|
||||
|
||||
//}
|
||||
|
||||
//{ Match
|
||||
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
|
||||
static int lcurl_match_callback(void *arg, const char *pattern, const char *string) {
|
||||
lcurl_easy_t *p = arg;
|
||||
lua_State *L = p->L;
|
||||
int ret = CURL_FNMATCHFUNC_NOMATCH;
|
||||
int top = lua_gettop(L);
|
||||
int n = lcurl_util_push_cb(L, &p->match);
|
||||
|
||||
assert(NULL != p->L);
|
||||
|
||||
lua_pushstring(L, pattern);
|
||||
lua_pushstring(L, string);
|
||||
|
||||
if (lua_pcall(L, n+1, LUA_MULTRET, 0)) {
|
||||
assert(lua_gettop(L) >= top);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_FNMATCHFUNC_FAIL;
|
||||
}
|
||||
|
||||
if(lua_gettop(L) > top){
|
||||
if(lua_isnil(L, top + 1) && (!lua_isnoneornil(L, top + 2))){
|
||||
lua_settop(L, top + 2);
|
||||
lua_remove(L, top + 1);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_FNMATCHFUNC_FAIL;
|
||||
}
|
||||
ret = lua_toboolean(L, top + 1) ? CURL_FNMATCHFUNC_MATCH : CURL_FNMATCHFUNC_NOMATCH;
|
||||
}
|
||||
|
||||
lua_settop(L, top);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcurl_easy_set_FNMATCH_FUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
return lcurl_easy_set_callback(L, p, &p->match,
|
||||
CURLOPT_FNMATCH_FUNCTION, CURLOPT_FNMATCH_DATA,
|
||||
"match", lcurl_match_callback
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//}
|
||||
|
||||
//{ Chunk begin/end
|
||||
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
|
||||
static int lcurl_chunk_bgn_callback(struct curl_fileinfo *info, void *arg, int remains) {
|
||||
lcurl_easy_t *p = arg;
|
||||
lua_State *L = p->L;
|
||||
int ret = CURL_CHUNK_BGN_FUNC_OK;
|
||||
int top = lua_gettop(L);
|
||||
int n = lcurl_util_push_cb(L, &p->chunk_bgn);
|
||||
|
||||
assert(NULL != p->L);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushstring (L, info->filename ); lua_setfield(L, -2, "filename" );
|
||||
lua_pushinteger(L, info->filetype ); lua_setfield(L, -2, "filetype" );
|
||||
lutil_pushint64(L, info->time ); lua_setfield(L, -2, "time" );
|
||||
lutil_pushint64(L, info->perm ); lua_setfield(L, -2, "perm" );
|
||||
lua_pushinteger(L, info->uid ); lua_setfield(L, -2, "uid" );
|
||||
lua_pushinteger(L, info->gid ); lua_setfield(L, -2, "gid" );
|
||||
lutil_pushint64(L, info->size ); lua_setfield(L, -2, "size" );
|
||||
lutil_pushint64(L, info->hardlinks ); lua_setfield(L, -2, "hardlinks" );
|
||||
lutil_pushint64(L, info->flags ); lua_setfield(L, -2, "flags" );
|
||||
|
||||
lua_newtable(L);
|
||||
if(info->strings.time) { lua_pushstring (L, info->strings.time ); lua_setfield(L, -2, "time" ); }
|
||||
if(info->strings.perm) { lua_pushstring (L, info->strings.perm ); lua_setfield(L, -2, "perm" ); }
|
||||
if(info->strings.user) { lua_pushstring (L, info->strings.user ); lua_setfield(L, -2, "user" ); }
|
||||
if(info->strings.group) { lua_pushstring (L, info->strings.group ); lua_setfield(L, -2, "group" ); }
|
||||
if(info->strings.target){ lua_pushstring (L, info->strings.target); lua_setfield(L, -2, "target"); }
|
||||
lua_setfield(L, -2, "strings");
|
||||
|
||||
lua_pushinteger(L, remains);
|
||||
|
||||
if (lua_pcall(L, n+1, LUA_MULTRET, 0)) {
|
||||
assert(lua_gettop(L) >= top);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_CHUNK_BGN_FUNC_FAIL;
|
||||
}
|
||||
|
||||
if(lua_gettop(L) > top){
|
||||
if(lua_isnil(L, top + 1) && (!lua_isnoneornil(L, top + 2))){
|
||||
lua_settop(L, top + 2);
|
||||
lua_remove(L, top + 1);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_CHUNK_BGN_FUNC_FAIL;
|
||||
}
|
||||
ret = lua_toboolean(L, top + 1) ? CURL_CHUNK_BGN_FUNC_OK : CURL_CHUNK_BGN_FUNC_SKIP;
|
||||
}
|
||||
|
||||
lua_settop(L, top);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcurl_chunk_end_callback(void *arg) {
|
||||
lcurl_easy_t *p = arg;
|
||||
lua_State *L = p->L;
|
||||
int ret = CURL_CHUNK_END_FUNC_OK;
|
||||
int top = lua_gettop(L);
|
||||
int n = lcurl_util_push_cb(L, &p->chunk_end);
|
||||
|
||||
assert(NULL != p->L);
|
||||
|
||||
if (lua_pcall(L, n-1, LUA_MULTRET, 0)) {
|
||||
assert(lua_gettop(L) >= top);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_CHUNK_END_FUNC_FAIL;
|
||||
}
|
||||
|
||||
if(lua_gettop(L) > top){
|
||||
if(lua_isnil(L, top + 1) && (!lua_isnoneornil(L, top + 2))){
|
||||
lua_settop(L, top + 2);
|
||||
lua_remove(L, top + 1);
|
||||
lua_pushlightuserdata(L, (void*)LCURL_ERROR_TAG);
|
||||
lua_insert(L, top + 1);
|
||||
return CURL_CHUNK_END_FUNC_FAIL;
|
||||
}
|
||||
ret = lua_toboolean(L, top + 1) ? CURL_CHUNK_END_FUNC_OK : CURL_CHUNK_END_FUNC_FAIL;
|
||||
}
|
||||
|
||||
lua_settop(L, top);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lcurl_easy_set_CHUNK_BGN_FUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
return lcurl_easy_set_callback(L, p, &p->chunk_bgn,
|
||||
CURLOPT_CHUNK_BGN_FUNCTION, CURLOPT_CHUNK_DATA,
|
||||
"chunk_bgn", lcurl_chunk_bgn_callback
|
||||
);
|
||||
}
|
||||
|
||||
static int lcurl_easy_set_CHUNK_END_FUNCTION(lua_State *L){
|
||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||
return lcurl_easy_set_callback(L, p, &p->chunk_end,
|
||||
CURLOPT_CHUNK_END_FUNCTION, CURLOPT_CHUNK_DATA,
|
||||
"chunk_end", lcurl_chunk_end_callback
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//}
|
||||
|
||||
//}
|
||||
|
||||
static int lcurl_easy_setopt(lua_State *L){
|
||||
@ -1036,6 +1361,13 @@ static int lcurl_easy_setopt(lua_State *L){
|
||||
OPT_ENTRY(readfunction, READFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(headerfunction, HEADERFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(progressfunction, PROGRESSFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(seekfunction, SEEKFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(debugfunction, DEBUGFUNCTION, TTT, 0, 0)
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_bgn_function, CHUNK_BGN_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_end_function, CHUNK_END_FUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,46,0)
|
||||
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
|
||||
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
|
||||
@ -1063,6 +1395,13 @@ static int lcurl_easy_unsetopt(lua_State *L){
|
||||
OPT_ENTRY(readfunction, READFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(headerfunction, HEADERFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(progressfunction, PROGRESSFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(seekfunction, SEEKFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(debugfunction, DEBUGFUNCTION, TTT, 0, 0)
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_bgn_function, CHUNK_BGN_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_end_function, CHUNK_END_FUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,46,0)
|
||||
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
|
||||
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
|
||||
@ -1134,6 +1473,13 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
|
||||
OPT_ENTRY(readfunction, READFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(headerfunction, HEADERFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(progressfunction, PROGRESSFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(seekfunction, SEEKFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(debugfunction, DEBUGFUNCTION, TTT, 0, 0)
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_bgn_function, CHUNK_BGN_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_end_function, CHUNK_END_FUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,46,0)
|
||||
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
|
||||
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
|
||||
@ -1149,6 +1495,13 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
|
||||
OPT_ENTRY(readfunction, READFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(headerfunction, HEADERFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(progressfunction, PROGRESSFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(seekfunction, SEEKFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(debugfunction, DEBUGFUNCTION, TTT, 0, 0)
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_bgn_function, CHUNK_BGN_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_end_function, CHUNK_END_FUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,46,0)
|
||||
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
|
||||
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
|
||||
@ -1189,6 +1542,13 @@ static const lcurl_const_t lcurl_easy_opt[] = {
|
||||
OPT_ENTRY(readfunction, READFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(headerfunction, HEADERFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(progressfunction, PROGRESSFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(seekfunction, SEEKFUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(debugfunction, DEBUGFUNCTION, TTT, 0, 0)
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_bgn_function, CHUNK_BGN_FUNCTION, TTT, 0, 0)
|
||||
OPT_ENTRY(chunk_end_function, CHUNK_END_FUNCTION, TTT, 0, 0)
|
||||
#endif
|
||||
#if LCURL_CURL_VER_GE(7,46,0)
|
||||
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
|
||||
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
|
||||
@ -1198,6 +1558,31 @@ static const lcurl_const_t lcurl_easy_opt[] = {
|
||||
|
||||
#define OPT_ENTRY(L, N, T, S) { "INFO_"#N, CURLINFO_##N },
|
||||
#include "lcinfoeasy.h"
|
||||
#undef OPT_ENTRY
|
||||
|
||||
#define OPT_ENTRY(N) { #N, CURL##N },
|
||||
// Debug message types not easy info
|
||||
OPT_ENTRY(INFO_TEXT )
|
||||
OPT_ENTRY(INFO_HEADER_IN )
|
||||
OPT_ENTRY(INFO_HEADER_OUT )
|
||||
OPT_ENTRY(INFO_DATA_IN )
|
||||
OPT_ENTRY(INFO_DATA_OUT )
|
||||
OPT_ENTRY(INFO_SSL_DATA_OUT )
|
||||
OPT_ENTRY(INFO_SSL_DATA_IN )
|
||||
|
||||
// File types for CURL_CHUNK_BGN_FUNCTION
|
||||
#if LCURL_CURL_VER_GE(7,21,0)
|
||||
OPT_ENTRY(FILETYPE_DEVICE_BLOCK )
|
||||
OPT_ENTRY(FILETYPE_DEVICE_CHAR )
|
||||
OPT_ENTRY(FILETYPE_DIRECTORY )
|
||||
OPT_ENTRY(FILETYPE_DOOR )
|
||||
OPT_ENTRY(FILETYPE_FILE )
|
||||
OPT_ENTRY(FILETYPE_NAMEDPIPE )
|
||||
OPT_ENTRY(FILETYPE_SOCKET )
|
||||
OPT_ENTRY(FILETYPE_SYMLINK )
|
||||
OPT_ENTRY(FILETYPE_UNKNOWN )
|
||||
#endif
|
||||
|
||||
#undef OPT_ENTRY
|
||||
|
||||
{NULL, 0}
|
||||
@ -1208,8 +1593,11 @@ void lcurl_easy_initlib(lua_State *L, int nup){
|
||||
/* Hack. We ensure that lcurl_easy_t and lcurl_hpost_stream_t
|
||||
compatiable for readfunction
|
||||
*/
|
||||
LCURL_STATIC_ASSERT(offsetof(lcurl_easy_t, magic) == offsetof(lcurl_hpost_stream_t, magic));
|
||||
LCURL_STATIC_ASSERT(sizeof(((lcurl_easy_t*)0)->magic) == sizeof(((lcurl_hpost_stream_t*)0)->magic));
|
||||
LCURL_ASSERT_SAME_OFFSET(lcurl_easy_t, magic, lcurl_hpost_stream_t, magic);
|
||||
LCURL_ASSERT_SAME_OFFSET(lcurl_easy_t, L, lcurl_hpost_stream_t, L);
|
||||
LCURL_ASSERT_SAME_OFFSET(lcurl_easy_t, rd, lcurl_hpost_stream_t, rd);
|
||||
LCURL_ASSERT_SAME_OFFSET(lcurl_easy_t, rbuffer, lcurl_hpost_stream_t, rbuffer);
|
||||
LCURL_ASSERT_SAME_FIELD_SIZE(lcurl_easy_t, rbuffer, lcurl_hpost_stream_t, rbuffer);
|
||||
|
||||
if(!lutil_createmetap(L, LCURL_EASY, lcurl_easy_methods, nup))
|
||||
lua_pop(L, nup);
|
||||
|
@ -60,6 +60,11 @@ typedef struct lcurl_easy_tag{
|
||||
lcurl_callback_t wr;
|
||||
lcurl_callback_t hd;
|
||||
lcurl_callback_t pr;
|
||||
lcurl_callback_t seek;
|
||||
lcurl_callback_t debug;
|
||||
lcurl_callback_t match;
|
||||
lcurl_callback_t chunk_bgn;
|
||||
lcurl_callback_t chunk_end;
|
||||
}lcurl_easy_t;
|
||||
|
||||
int lcurl_easy_create(lua_State *L, int error_mode);
|
||||
|
@ -28,8 +28,13 @@
|
||||
#define LCURL_MAKE_VERSION(MIN, MAJ, PAT) ((MIN<<16) + (MAJ<<8) + PAT)
|
||||
#define LCURL_CURL_VER_GE(MIN, MAJ, PAT) (LIBCURL_VERSION_NUM >= LCURL_MAKE_VERSION(MIN, MAJ, PAT))
|
||||
|
||||
//! @fixme on mingw32 (gcc 4.8.1) this does not work
|
||||
#define LCURL_STATIC_ASSERT(A) {(void)(int(*)[(A)?1:0])0;}
|
||||
#define LCURL_CONCAT_STATIC_ASSERT_IMPL_(x, y) LCURL_CONCAT1_STATIC_ASSERT_IMPL_ (x, y)
|
||||
#define LCURL_CONCAT1_STATIC_ASSERT_IMPL_(x, y) x##y
|
||||
#define LCURL_STATIC_ASSERT(expr) typedef char LCURL_CONCAT_STATIC_ASSERT_IMPL_(static_assert_failed_at_line_, __LINE__) [(expr) ? 1 : -1]
|
||||
|
||||
#define LCURL_ASSERT_SAME_SIZE(a, b) LCURL_STATIC_ASSERT( sizeof(a) == sizeof(b) )
|
||||
#define LCURL_ASSERT_SAME_OFFSET(a, am, b, bm) LCURL_STATIC_ASSERT( (offsetof(a,am)) == (offsetof(b,bm)) )
|
||||
#define LCURL_ASSERT_SAME_FIELD_SIZE(a, am, b, bm) LCURL_ASSERT_SAME_SIZE(((a*)0)->am, ((b*)0)->bm)
|
||||
|
||||
typedef struct lcurl_const_tag{
|
||||
const char *name;
|
||||
|
Loading…
x
Reference in New Issue
Block a user