lua-curl-0.3.0/0000755000175000017500000000000011100635242012260 5ustar tassitassilua-curl-0.3.0/exclude-dist0000644000175000017500000000007411100635242014576 0ustar tassitassi.svn CVS lua5_1_4_Win32_bin.zip lua5_1_4_Win32_dll8_lib.zip lua-curl-0.3.0/lua-curl.c0000644000175000017500000011332611100635242014156 0ustar tassitassi/****************************************************************************** cURL_Lua, Lua bindings for cURL ****************************************************************************** Released under the GNU/GPL license or MIT license (at your option), no warranties. Author: - Enrico Tassi status: - binds from 7.9.5 to 7.18.1 changelog: - revamped to libcurl 7.18.1 - fixed large file support - added a Makefile based on libtool as suggested in the debian package of lua5.1 - first public release todo: - WRITE_CB,READ_CB,DEBUG_CB must be identifyed by a unique pointer, but using CURL* + OFFSET may not be the case... think a bit more - CURLINFO ??? - CURLOPT_COPYPOSTFIELDS missing: - CURLOPT_IOCTLFUNCTION/DATA - CURLOPT_SOCKOPTFUNCTION/DATA - CURLOPT_OPENSOCKETFUNCTION/DATA - CURLOPT_SEEKFUNCTION/DATA ****************************************************************************** $Id: lua-curl.c,v 1.6 2008/10/25 14:38:29 gareuselesinge Exp $ ******************************************************************************/ #include #include #include #include #include #include #include #include "luabind.h" #include "version.h" #if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 #include "compat-5.1.h" #endif #define CURL_EASY_META_NAME "curleasy.type" /* think more if this means unicity... maybe store in the bag some pointers */ /* this need that a has size > bigger_offset */ #define CURL_WRITECB_OFF(a) ((void*)(((char*)a)+0)) #define CURL_READCB_OFF(a) ((void*)(((char*)a)+1)) #define CURL_HEADCB_OFF(a) ((void*)(((char*)a)+2)) /* to check the curl version on the fly, this is a v >= LIBCURL_VERSION */ #define CURL_NEWER(M,m,p) ((p + (m << 8) + (M << 16)) <= LIBCURL_VERSION_NUM) #define CURL_OLDER(M,m,p) ((p + (m << 8) + (M << 16)) > LIBCURL_VERSION_NUM) /* some compatibility for name aliases */ #ifndef CURLOPT_WRITEDATA #define CURLOPT_WRITEDATA CURLOPT_FILE #endif #ifndef CURLOPT_READDATA #define CURLOPT_READDATA CURLOPT_INFILE #endif #ifndef CURLOPT_HEADERDATA #define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER #endif /* strings put in the bag, vectorialized for faster/shorter access */ #define STR_CAINFO 0 #define STR_COOKIE 1 #define STR_COOKIEFILE 2 #define STR_COOKIEJAR 3 #define STR_CUSTOMREQUEST 4 #define STR_EGDSOCKET 5 #define STR_FTPPORT 6 #define STR_INTERFACE 7 #define STR_KRB4LEVEL 8 #define STR_POSTFIELDS 9 #define STR_PROXY 10 #define STR_PROXYUSERPWD 11 #define STR_RANDOM_FILE 12 #define STR_RANGE 13 #define STR_REFERER 14 #define STR_SSLCERT 15 #define STR_SSLCERTPASSWD 16 #define STR_SSLCERTTYPE 17 #define STR_SSLENGINE 18 #define STR_SSLKEY 19 #define STR_SSLKEYTYPE 20 #define STR_SSL_CIPHER_LIST 21 #define STR_URL 22 #define STR_USERAGENT 23 #define STR_USERPWD 24 #define STR_LAST STR_USERPWD #if CURL_NEWER(7,9,8) #define STR_CAPATH 25 #undef STR_LAST #define STR_LAST STR_CAPATH #endif #if CURL_NEWER(7,10,0) #define STR_ENCODING 26 #undef STR_LAST #define STR_LAST STR_ENCODING #endif #if CURL_NEWER(7,10,3) #define STR_PRIVATE 27 #undef STR_LAST #define STR_LAST STR_PRIVATE #endif #if CURL_NEWER(7,11,0) #define STR_NETRC_FILE 28 #undef STR_LAST #define STR_LAST STR_NETRC_FILE #endif #define STR_SIZE (STR_LAST + 1) /****************************************************************************** * we need to keep with us the CURL handler plus some buffers * */ struct L_curl_bag { CURL* handler; char* strings[STR_SIZE]; char err[CURL_ERROR_SIZE]; struct curl_slist * headlist; #if CURL_NEWER(7,9,6) struct curl_httppost *post; #endif }; /****************************************************************************** * table created with this script: * * cat /usr/include/curl/curl.h | grep "^ *CINIT(" | \ * sed "s/CINIT(/{\"OPT_/" | sed -r "s/, +/\",CURLOPTTYPE_/" | \ * sed "s/, / + /" | sed "s/),/},/" > curlopt.h * */ static const struct L_const curl_easy_c [] = { #include "curlopt.h" {NULL,0} }; /****************************************************************************** * table created with this script: * * cat /usr/include/curl/curl.h | grep "^ *CURL_NETRC_[A-Z]*," | \ * cut -f 1 -d "," | \ * awk '{print "{\"" $1 "\", (int)" $1 "}," }' | \ * sed "s/CURL_//" > curl_netrcopt.h */ #if CURL_NEWER(7,9,8) static const struct L_const curl_easy_netrc_c [] = { #include "curl_netrcopt.h" {NULL,0} }; #endif /****************************************************************************** * table created with this script: * * cat /usr/include/curl/curl.h | grep "CURLAUTH_" | \ * sed "s/#define *CURL/{\"/" | sed "s/ *\/\*.*\*\///" | \ * sed "s/ /\",/" | sed "s/$$/},/" > curl_authopt.h */ #if CURL_NEWER(7,10,6) static const struct L_const curl_easy_auth_c [] = { #include "curl_authopt.h" {NULL,0} }; #endif /****************************************************************************** * table created with this script: * * cat /usr/include/curl/curl.h | grep -B10 '} curl_ftpauth' | \ * grep "CURLFTPAUTH_" | \ * grep -v "LAST.*never use" | \ * sed "s/^ *CURL//" | sed "s/^\([^,]*\),.*$$/{\"\1\",CURL\1},/" \ * > curl_ftpauthopt.h */ #if CURL_NEWER(7,12,2) static const struct L_const curl_easy_ftpauth_c [] = { #include "curl_ftpauthopt.h" {NULL,0} }; #endif /****************************************************************************** * table created with this script: * * cat /usr/include/curl/curl.h | grep -B10 '} curl_ftpmethod' | \ * grep "CURLFTPMETHOD_" | \ * grep -v "LAST.*never use" | \ * sed "s/^ *CURL//" | sed "s/^\([^,]*\),.*$$/{\"\1\",CURL\1},/" \ * > curl_ftpmethods.h */ #if CURL_NEWER(7,15,2) static const struct L_const curl_easy_ftpmethods_c [] = { #include "curl_ftpmethods.h" {NULL,0} }; #endif /****************************************************************************** * table created by hand: * */ static const struct L_const curl_easy_httpver_c [] = { {"HTTP_VERSION_NONE",CURL_HTTP_VERSION_NONE}, {"HTTP_VERSION_1_0",CURL_HTTP_VERSION_1_0}, {"HTTP_VERSION_1_1",CURL_HTTP_VERSION_1_1}, {NULL,0} }; /****************************************************************************** * table created by hand: * */ #if CURL_NEWER(7,11,0) static const struct L_const curl_easy_ftpssl_c [] = { {"FTPSSL_NONE",CURLFTPSSL_NONE}, {"FTPSSL_TRY",CURLFTPSSL_TRY}, {"FTPSSL_CONTROL",CURLFTPSSL_CONTROL}, {"FTPSSL_ALL",CURLFTPSSL_ALL}, {NULL,0} }; #endif /****************************************************************************** * table created by hand: * */ static const struct L_const curl_easy_closepolicy_c [] = { {"CLOSEPOLICY_LEAST_RECENTLY_USED",CURLCLOSEPOLICY_LEAST_RECENTLY_USED}, {"CLOSEPOLICY_OLDEST",CURLCLOSEPOLICY_OLDEST}, {NULL,0} }; /****************************************************************************** * table created by hand: * */ #if CURL_NEWER(7,10,8) static const struct L_const curl_easy_ipresolve_c [] = { {"IPRESOLVE_WHATEVER",CURL_IPRESOLVE_WHATEVER}, {"IPRESOLVE_V4",CURL_IPRESOLVE_V4}, {"IPRESOLVE_V6",CURL_IPRESOLVE_V6}, {NULL,0} }; #endif /****************************************************************************** * table created by hand: * */ #if CURL_NEWER(7,10,0) static const struct L_const curl_easy_proxytype_c [] = { {"PROXY_HTTP",CURLPROXY_HTTP}, {"PROXY_SOCKS5",CURLPROXY_SOCKS5}, {NULL,0} }; #endif /****************************************************************************** * table created with this script: * * cat /usr/include/curl/curl.h | grep "^ *CFINIT" | \ * grep -v "CFINIT(NOTHING)" | sed "s/CFINIT(//" | \ * sed "s/),/ ,/" | \ * awk '{print "{\"FORM_" $1 "\",CURLFORM_" $1 "}," }' > \ * curl_form.h */ static const struct L_const curl_easy_form_c [] = { #include "curl_form.h" {NULL,0} }; /****************************************************************************** * checks and returns a CURL* handler from the first position in the stack * */ static CURL* L_checkcurleasy(lua_State*L) { void* tmp = luaL_checkudata(L,1,CURL_EASY_META_NAME); luaL_argcheck(L,tmp != NULL,1,"curleasy expected"); return ((struct L_curl_bag*)tmp)->handler; } /****************************************************************************** * checks and returns the userdata * */ static struct L_curl_bag* L_checkcurluserdata(lua_State*L) { void* tmp = luaL_checkudata(L,1,CURL_EASY_META_NAME); luaL_argcheck(L,tmp != NULL,1,"curleasy expected"); return ((struct L_curl_bag*)tmp); } /****************************************************************************** * maps a curl option to the right bag.strings[] element * */ static unsigned int L_CURLoption2vect(lua_State*L,CURLoption opt){ switch (opt) { case CURLOPT_CAINFO: return STR_CAINFO; case CURLOPT_COOKIE: return STR_COOKIE; case CURLOPT_COOKIEFILE: return STR_COOKIEFILE; case CURLOPT_COOKIEJAR: return STR_COOKIEJAR; case CURLOPT_CUSTOMREQUEST: return STR_CUSTOMREQUEST; case CURLOPT_EGDSOCKET: return STR_EGDSOCKET; case CURLOPT_FTPPORT: return STR_FTPPORT; case CURLOPT_INTERFACE: return STR_INTERFACE; case CURLOPT_KRB4LEVEL: return STR_KRB4LEVEL; case CURLOPT_POSTFIELDS: return STR_POSTFIELDS; case CURLOPT_PROXY: return STR_PROXY; case CURLOPT_PROXYUSERPWD: return STR_PROXYUSERPWD; case CURLOPT_RANDOM_FILE: return STR_RANDOM_FILE; case CURLOPT_RANGE: return STR_RANGE; case CURLOPT_REFERER: return STR_REFERER; case CURLOPT_SSLCERT: return STR_SSLCERT; case CURLOPT_SSLCERTPASSWD: return STR_SSLCERTPASSWD; case CURLOPT_SSLCERTTYPE: return STR_SSLCERTTYPE; case CURLOPT_SSLENGINE: return STR_SSLENGINE; case CURLOPT_SSLKEY: return STR_SSLKEY; case CURLOPT_SSLKEYTYPE: return STR_SSLKEYTYPE; case CURLOPT_SSL_CIPHER_LIST: return STR_SSL_CIPHER_LIST; case CURLOPT_URL: return STR_URL; case CURLOPT_USERAGENT: return STR_USERAGENT; case CURLOPT_USERPWD: return STR_USERPWD; #if CURL_NEWER(7,9,8) case CURLOPT_CAPATH: return STR_CAPATH; #endif #if CURL_NEWER(7,10,0) case CURLOPT_ENCODING: return STR_ENCODING; #endif #if CURL_NEWER(7,10,3) case CURLOPT_PRIVATE: return STR_PRIVATE; #endif #if CURL_NEWER(7,11,0) case CURLOPT_NETRC_FILE: return STR_NETRC_FILE; #endif default: L_error(L,"Unsupported string in bag"); } return 0; } /****************************************************************************** * checks and returns a string field from the first position in the stack * */ static char** L_checkcurlstring(lua_State*L,CURLoption opt) { struct L_curl_bag* tmp = (struct L_curl_bag*) luaL_checkudata(L,1,CURL_EASY_META_NAME); luaL_argcheck(L,tmp != NULL,1,"curleasy expected"); return &(tmp->strings[L_CURLoption2vect(L,opt)]); } /****************************************************************************** * checks and returns the header slist * */ static struct curl_slist ** L_checkcurlheadlist(lua_State*L) { struct L_curl_bag* tmp = (struct L_curl_bag*) luaL_checkudata(L,1,CURL_EASY_META_NAME); luaL_argcheck(L,tmp != NULL,1,"curleasy expected"); return &(tmp->headlist); } /****************************************************************************** * checks and returns the err field from the first position in the stack * */ static char* L_checkcurlerr(lua_State*L) { void* tmp = luaL_checkudata(L,1,CURL_EASY_META_NAME); luaL_argcheck(L,tmp != NULL,1,"curleasy expected"); return ((struct L_curl_bag*)tmp)->err; } /****************************************************************************** * checks and returns the post field from the first position in the stack * */ #if CURL_NEWER(7,9,6) static struct curl_httppost **L_checkcurlpost(lua_State*L){ void* tmp = luaL_checkudata(L,1,CURL_EASY_META_NAME); luaL_argcheck(L,tmp != NULL,1,"curleasy expected"); return &((struct L_curl_bag*)tmp)->post; } #endif /****************************************************************************** * checks if c is_in t and returns it * */ static long L_checkconst(lua_State* L, const struct L_const* t,const char* t_nam, int c){ int i,found; long int con; if( lua_type(L,c) != LUA_TNUMBER) L_error(L,"Expecting a %s value, got %s",t_nam, lua_typename(L,lua_type(L,c))); con = (long int)lua_tonumber(L,c); for ( i = 0,found = 0 ; t[i].name != NULL ; i++){ if( t[i].value == con){ found = 1; break; } } if(found == 1) return con; else { L_error(L,"Expecting a %s value, got something else",t_nam); } return -1; } /****************************************************************************** * checks if c is <= \sigma t and returns it * */ static long int L_checkconst_mask(lua_State* L, const struct L_const* t,const char* t_nam, int c){ int con; if( lua_type(L,c) != LUA_TNUMBER ) L_error(L,"Expecting a %s value, got nothing",t_nam); //FIXME: think a check con = (long int)lua_tonumber(L,c); return con; } /****************************************************************************** * checks, builds and return a string list * */ static struct curl_slist * L_checkslist(lua_State* L,int tab_index) { struct curl_slist * sl = NULL; /* since we manipulate the stack we want tab_index in absolute */ if ( tab_index < 0 ) tab_index = lua_gettop(L) + 1 + tab_index; /* a slist must be a LUA table */ luaL_argcheck(L,lua_istable(L,tab_index),tab_index,"expecting a table"); /* create the slist */ sl = NULL; /* traverse the table */ lua_pushnil(L); while( lua_next(L,tab_index) != 0 ){ const char * val; /* now we have: ...old_stack... | key:int | val:string */ if ( lua_type(L,-1) != LUA_TSTRING) { curl_slist_free_all(sl); L_error(L,"this table must be a string list"); } if ( lua_type(L,-2) != LUA_TNUMBER ) { curl_slist_free_all(sl); L_error(L,"this table is a list, keys must be unused"); } /* get the string */ val = lua_tostring(L,-1); /* pop val */ lua_pop(L,1); /* store it in the list */ sl = curl_slist_append(sl,val); } return sl; } /****************************************************************************** * curl_easy_perform * */ static int luacurl_easy_perform(lua_State* L) { CURL* c = L_checkcurleasy(L); CURLcode rc = curl_easy_perform(c); L_checknarg(L,1,"perform wants 1 argument (self)"); if ( rc == CURLE_OK ) { lua_pushnumber(L,(lua_Number)rc); lua_pushnil(L); }else{ lua_pushnumber(L,(lua_Number)rc); lua_pushstring(L,L_checkcurlerr(L)); } return 2; } /****************************************************************************** * curl write callback * */ static size_t L_callback_writedata( void *ptr,size_t size,size_t nmemb,void *stream){ lua_State* L = (lua_State*)stream; size_t rc; size_t dimension = size * nmemb; L_checknarg(L,1,"we expect the callback to have a curl handler on the stack"); /* find the lua closure */ /* XXX we assume the c:perform() leaves c on the stack */ lua_pushlightuserdata(L,CURL_WRITECB_OFF(L_checkcurleasy(L))); lua_rawget(L,LUA_REGISTRYINDEX); /* call it */ lua_pushlstring(L,(const char *)ptr,dimension); lua_pushnumber(L,dimension); lua_call(L,2,2); L_checknarg(L,3,"we expect the callback to return 2 arguments"); if (lua_type(L,-2) != LUA_TNUMBER) L_error(L,"head_cb must return: (number,errror_message or nil) but the " "first one is not a number"); rc = (size_t)lua_tonumber(L,-2); /* if( rc != dimension ) { if ( lua_type(L,-1) == LUA_TSTRING) L_error(L,"write_cb returned %d that is not the expected %d" ", error message: '%s'",rc,dimension,lua_tostring(L,-1)); else L_error(L,"write_cb returned %d that is not the expected %d" ", no error message",rc,dimension); } */ lua_pop(L,2); return rc; } /****************************************************************************** * curl write header callback * */ static size_t L_callback_writehead( void *ptr,size_t size,size_t nmemb,void *stream){ lua_State* L = (lua_State*)stream; size_t rc; size_t dimension = size * nmemb; L_checknarg(L,1,"we expect the callback to have a curl handler on the stack"); /* find the lua closure */ /* XXX we assume the c:perform() leaves c on the stack */ lua_pushlightuserdata(L,CURL_HEADCB_OFF(L_checkcurleasy(L))); lua_rawget(L,LUA_REGISTRYINDEX); /* call it */ lua_pushlstring(L,(const char *)ptr,dimension); lua_pushnumber(L,dimension); lua_call(L,2,2); L_checknarg(L,3,"we expect the callback to return 2 arguments"); if (lua_type(L,-2) != LUA_TNUMBER) L_error(L,"head_cb must return: (number,errror_message or nil) but the " "first one is not a number"); rc = (size_t)lua_tonumber(L,-2); /* if( rc != dimension ) { if ( lua_type(L,-1) == LUA_TSTRING) L_error(L,"head_cb returned %d that is not the expected %d" ", error message: '%s'",rc,dimension,lua_tostring(L,-1)); else L_error(L,"head_cb returned %d that is not the expected %d" ", no error message",rc,dimension); } */ lua_pop(L,2); return rc; } /****************************************************************************** * curl read callback * */ static size_t L_callback_readdata( void *ptr,size_t size,size_t nmemb,void *stream){ lua_State* L = (lua_State*)stream; size_t rc; size_t dimension = size * nmemb; L_checknarg(L,1,"we expect the callback to have a curl handler on the stack"); /* find the lua closure */ /* XXX we assume the c:perform() leaves c on the stack */ lua_pushlightuserdata(L,CURL_READCB_OFF(L_checkcurleasy(L))); lua_rawget(L,LUA_REGISTRYINDEX); /* call it */ lua_pushnumber(L,dimension); lua_call(L,1,2); L_checknarg(L,3,"we expect the callback to return 2 arguments"); if (lua_type(L,-2) != LUA_TNUMBER) L_error(L,"read_cb must return: (number,errror_message or nil) but the " "first one is not a number"); rc = (size_t)lua_tonumber(L,-2); if(rc != 0) { /* we have data to send */ if ( rc > dimension ) L_error(L,"read_rc must return a size <= than the number " "that received in input"); if ( lua_type(L,-1) != LUA_TSTRING) L_error(L,"read_cb must return a string as the second " "value, not a %s",lua_typename(L,lua_type(L,-1))); if ( rc != lua_strlen(L,-1) ) L_error(L,"read_cb must return a size and a string, " "and the size must be the string size"); memcpy(ptr,lua_tostring(L,-1),rc); } lua_pop(L,2); return rc; } /****************************************************************************** * CURLOPT_HTTPPOST parser * */ #if CURL_NEWER(7,9,8) static CURLcode L_httppost(CURL* c,CURLoption opt,lua_State* L){ /* we assume we hve stack: || c | opt | table * * table is a table of tables since we assume the function is called: * c:setopt(curl.OPT_HTTPPOST,{ * {curl.FORM_COPYNAME,"name1", * curl.FORM_COPYCONTENTS,"data1", * curl.FORM_CONTENTTYPE,"Content-type: text/plain", * curl.FORM_END}, * {curl.FORM_COPYNAME,"name2", * curl.FORM_COPYCONTENTS,"data2", * curl.FORM_CONTENTTYPE,"Content-type: text/plain", * curl.FORM_END} * }) * */ struct curl_httppost *post = NULL, *last = NULL; #if CURL_NEWER(7,9,8) CURLFORMcode rc = CURL_FORMADD_OK; #else int rc = CURL_FORMADD_OK; #endif CURLcode rc_opt = CURLE_OK; /* check for the table */ if( ! lua_istable(L,3) ) L_error(L,"expecting a table, got %s",lua_typename(L,lua_type(L,3))); /* outer loop to travers the table list */ lua_pushnil(L); while( lua_next(L,3) != 0 ){ /* now we have: ...old_stack... | key:int | val:table * and we traverse the internal table */ int forms_size = L_tablesize(L,5)/2+1; struct curl_forms forms[forms_size]; /* not ANSI */ int position = 0; lua_pushnil(L); while( lua_next(L,5) != 0 ){ CURLformoption o = (CURLformoption) L_checkconst(L,curl_easy_form_c,"CURLformoption",7); switch(o){ case CURLFORM_BUFFER: case CURLFORM_BUFFERPTR: case CURLFORM_FILENAME: case CURLFORM_CONTENTTYPE: /* sould be ok */ case CURLFORM_FILE: case CURLFORM_FILECONTENT: case CURLFORM_PTRCONTENTS: case CURLFORM_COPYCONTENTS: case CURLFORM_PTRNAME: case CURLFORM_COPYNAME:{ forms[position].option = o; lua_pop(L,1); if(lua_next(L,5) == 0) L_error(L, "incomplete FORM, value missed"); forms[position].value = luaL_checkstring(L,7); }break; case CURLFORM_BUFFERLENGTH:{ forms[position].option = o; lua_pop(L,1); if(lua_next(L,5) == 0) L_error(L, "incomplete FORM, value missed"); forms[position].value = (char*) #ifdef __UWORD_TYPE (__UWORD_TYPE) #endif //not sure this makes sense luaL_checkint(L,7); }break; case CURLFORM_CONTENTHEADER:{ /* we need a damned bag here! */ L_error(L,"not implemented, use " "CURLFORM_CONTENTTYPE instead"); }break; case CURLFORM_END:{ forms[position].option = o; }break; case CURLFORM_ARRAY:{ L_error(L,"You can't use CURLFORM_ARRAY"); }break; default:{ L_error(L,"invalid CURLFORM_"); }break; } position++; lua_pop(L,1); } if ( (positionhandler = tmp; for(i = 0 ; i < STR_SIZE ; i++) c->strings[i] = NULL; c->headlist = NULL; #if CURL_NEWER(7,9,6) c->post=NULL; #endif rc = curl_easy_setopt(tmp,CURLOPT_ERRORBUFFER,c->err); /* check for errors */ if( rc != CURLE_OK) { L_error(L,"unable to call CURLOPT_ERRORBUFFER (%d)",rc); } return 1; } /****************************************************************************** * curl_easy_cleanup * */ static int luacurl_easy_cleanup(lua_State* L) { struct L_curl_bag* c = L_checkcurluserdata(L); int i; curl_easy_cleanup(c->handler); for(i = 0 ; i < STR_SIZE ; i++) free(c->strings[i]); curl_slist_free_all(c->headlist); #if CURL_NEWER(7,9,6) if(c->post != NULL) curl_formfree(c->post); #endif lua_pushlightuserdata(L,CURL_WRITECB_OFF(c)); lua_pushnil(L); lua_rawset(L,LUA_REGISTRYINDEX); lua_pushlightuserdata(L,CURL_READCB_OFF(c)); lua_pushnil(L); lua_rawset(L,LUA_REGISTRYINDEX); lua_pushlightuserdata(L,CURL_HEADCB_OFF(c)); lua_pushnil(L); lua_rawset(L,LUA_REGISTRYINDEX); return 0; } /****************************************************************************** * curl_escape * */ static int luacurl_escape(lua_State* L) { const char* data = luaL_checkstring(L,1); size_t len = lua_strlen(L,1); char * tmp; L_checknarg(L,1,"escape wants 1 argument (string)"); tmp = curl_escape(data,len); lua_pushstring(L,tmp); #if CURL_NEWER(7,10,0) curl_free(tmp); #else free(tmp); #endif return 1; } /****************************************************************************** * curl_unescape * */ static int luacurl_unescape(lua_State* L) { const char* data = luaL_checkstring(L,1); size_t len = lua_strlen(L,1); char * tmp; L_checknarg(L,1,"unescape wants 1 argument (string)"); tmp = curl_unescape(data,len); lua_pushstring(L,tmp); #if CURL_NEWER(7,10,0) curl_free(tmp); #else free(tmp); #endif return 1; } /****************************************************************************** * curl_version * */ static int luacurl_version(lua_State* L) { L_checknarg(L,0,"version wants no arguments"); lua_pushstring(L,curl_version()); return 1; } /****************************************************************************** * curl_version_info * */ #if CURL_NEWER(7,10,0) static int luacurl_version_info(lua_State* L) { curl_version_info_data *d = curl_version_info(CURLVERSION_NOW); int i; L_checknarg(L,0,"version_info wants no arguments"); lua_newtable(L); lua_pushstring(L,"version"); lua_pushstring(L,d->version); lua_settable(L,-3); lua_pushstring(L,"version_num"); lua_pushnumber(L,d->version_num); lua_settable(L,-3); lua_pushstring(L,"host"); lua_pushstring(L,d->host); lua_settable(L,-3); lua_pushstring(L,"ssl_version"); lua_pushstring(L,d->ssl_version); lua_settable(L,-3); lua_pushstring(L,"ssl_version_num"); lua_pushnumber(L,d->ssl_version_num); lua_settable(L,-3); lua_pushstring(L,"features"); lua_pushnumber(L,d->features); lua_settable(L,-3); lua_pushstring(L,"libz_version"); lua_pushstring(L,d->libz_version); lua_settable(L,-3); lua_pushstring(L,"protocols"); lua_newtable(L); for(i=0;d->protocols[i] != NULL;i++){ lua_pushnumber(L,i+1); lua_pushstring(L,d->protocols[i]); lua_settable(L,-3); } lua_pushstring(L,"n"); lua_pushnumber(L,i); lua_settable(L,-3); lua_settable(L,-3); return 1; } #endif /****************************************************************************** * curl.* functions * */ static const struct luaL_reg curl_f [] = { {"easy_init",luacurl_easy_init}, {"escape",luacurl_escape}, {"unescape",luacurl_unescape}, {"version",luacurl_version}, #if CURL_NEWER(7,10,0) {"version_info",luacurl_version_info}, #endif {NULL,NULL} }; /****************************************************************************** * c:* functions * */ static const struct luaL_reg curl_easy_m [] = { {"setopt",luacurl_easy_setopt}, {"perform",luacurl_easy_perform}, {NULL,NULL} }; /****************************************************************************** * open the luacurl library * you need to call curl_global_init manually * */ int luacurl_open(lua_State* L) { luaL_newmetatable(L,CURL_EASY_META_NAME); lua_pushstring(L,"__gc"); lua_pushcfunction(L,luacurl_easy_cleanup); lua_settable(L,-3); lua_pushstring(L,"__index"); lua_pushvalue(L,-2); lua_settable(L,-3); luaL_register(L,NULL,curl_easy_m); luaL_register(L,"curl",curl_f); lua_pushliteral(L,LUACURL_VERSION); lua_setfield(L,-2,"_VERSION"); lua_pushliteral(L,LUACURL_AUTHOR); lua_setfield(L,-2,"_AUTHOR"); lua_pushliteral(L,LUACURL_LICENSE); lua_setfield(L,-2,"_LICENSE"); L_openconst(L,curl_easy_c); L_openconst(L,curl_easy_httpver_c); L_openconst(L,curl_easy_form_c); L_openconst(L,curl_easy_closepolicy_c); #if CURL_NEWER(7,9,8) L_openconst(L,curl_easy_netrc_c); #endif #if CURL_NEWER(7,10,0) L_openconst(L,curl_easy_proxytype_c); #endif #if CURL_NEWER(7,10,6) L_openconst(L,curl_easy_auth_c); #endif #if CURL_NEWER(7,10,8) L_openconst(L,curl_easy_ipresolve_c); #endif #if CURL_NEWER(7,11,0) L_openconst(L,curl_easy_ftpssl_c); #endif #if CURL_NEWER(7,12,2) L_openconst(L,curl_easy_ftpauth_c); #endif #if CURL_NEWER(7,15,2) L_openconst(L,curl_easy_ftpmethods_c); #endif return 1; } /****************************************************************************** * opens the luacurl library and calls curl_global_init(CURL_GLOBAL_ALL) * use this if you have not initialized cURL in the C code * */ int luacurl_open_and_init(lua_State* L) { // can be called multiple times without troubles curl_global_init(CURL_GLOBAL_ALL); return luacurl_open(L); } int luaopen_curl(lua_State* L) { return luacurl_open_and_init(L); } // eof lua-curl-0.3.0/test-largeput.lua0000644000175000017500000000103211100635242015557 0ustar tassitassi-- test file that sends a large blob: test for OPT_INFILESIZE_LARGE require "curl" size = 2^32+1 c = curl.easy_init() c:setopt(curl.OPT_PUT,1) c:setopt(curl.OPT_URL,"http://127.0.0.1:3000") c:setopt(curl.OPT_READFUNCTION,function(n) return n, string.rep("X",n) end) c:setopt(curl.OPT_INFILESIZE_LARGE, size) c:setopt(curl.OPT_VERBOSE,1) -- run a black hole os.execute("nc -l -p 3000 > /dev/null &") -- wait for nc to bind the socket os.execute("sleep 3") -- go! print("\nluacurl: performing put of size: " .. size .."\n") c:perform() lua-curl-0.3.0/lua-curl.h0000644000175000017500000000033611100635242014157 0ustar tassitassi#ifndef CURL_LUA_H #define CURL_LUA_H int luacurl_freepops_open_and_init(lua_State* L); int luacurl_freepops_open(lua_State* L); // to be loaded from the toplevel (calls init too) int luaopen_curl(lua_State* L); #endif lua-curl-0.3.0/luabind.h0000644000175000017500000000340311100635242014047 0ustar tassitassi/****************************************************************************** * $Id: luabind.h,v 1.4 2008/10/25 11:58:03 gareuselesinge Exp $ * This file is part of FreePOPs (http://www.freepops.org) * * This file is distributed under the terms of GNU GPL license or, at your * * option, MIT license. * ******************************************************************************/ /******************************************************************************/ /*! * \file luabind.h * \brief functions to help in creating bindings * * \author Name */ /******************************************************************************/ #ifndef LUABIND_H #define LUABIND_H // fill an array of this this with {"NAME",value} and terminate it with {NULL,0} // and pass it to L_openconst struct L_const{ char* name; unsigned int value; }; // fill an array of this this with {"NAME",value} and // terminate it with {NULL,NULL} // and pass it to L_openconst_with_type struct L_Tuserdata{ char* name; void* data; }; // a more flexibla luaL_error void L_error(lua_State* L, char* msg, ...); // returns the table at position n in the stack int L_tablesize(lua_State* L,int n); // checks if we received n arguments, if not we raise an error void L_checknarg(lua_State* L,int n,char* msg); // given a table on top of the stack we add all constats to it void L_openconst(lua_State* L,const struct L_const* t); // given a table on top of the stack we add all constats with type to it void L_openTconst(lua_State* L,const struct L_Tuserdata* t,const char * type); // since there is no luaL_checklightuserdata void * L_checkludata(lua_State* L,int n); #endif lua-curl-0.3.0/Makefile0000644000175000017500000001474311100635242013731 0ustar tassitassi# TODO: support for abi&libtool, installation of lua-curl.h LIBNAME=liblua5.1-curl LIBTOOL=libtool --silent --tag=CC HEADER=/usr/include/curl/curl.h PREFIX=/usr/local/ #LUA=lua50 LUA=lua5.1 LUADOC= luadoc VERSION_INFO=0:0:0 CONSTANTS:= curlopt.h curl_netrcopt.h \ curl_form.h curl_authopt.h curl_ftpauthopt.h curl_ftpmethods.h CURL_CFLAGS:= $(shell curl-config --cflags 2>/dev/null) $(shell getconf LFS_CFLAGS) CURL_LDFLAGS:= $(shell curl-config --libs 2>/dev/null) REALSO:=$(LIBNAME).so.$(subst :,.,$(VERSION_INFO)) # ------------------------------ lua5.1 stuff --------------------------------- ifeq "$(LUA)" "lua5.1" LUA_CFLAGS := $(shell pkg-config lua5.1 --cflags) $(shell getconf LFS_CFLAGS) # This retrieves the name of the libtool convenience library for Lua # (e.g. "/usr/lib/liblua5.1.la") used by --mode=link. LUA_LIBTOOL_S := $(shell pkg-config lua5.1 --variable=libtool_lib) LUA_LIBTOOL_D := $(LUA_LIBTOOL_S) # this is the path where you'll eventually install the module LUA_RPATH:=$(shell pkg-config lua5.1 --define-variable=prefix=$(PREFIX) \ --variable=INSTALL_CMOD) # this is the path where you'll eventually install the C header file LUA_HPATH:=$(shell pkg-config lua5.1 --define-variable=prefix=$(PREFIX) \ --variable=includedir)/lua5.1 LUA_DPATH:=$(PREFIX)/share/doc/luacurl/ LUA_LPATH:=$(PREFIX)/lib/ OBJS:= lua-curl.lo luabind.lo endif # ------------------------------ lua50 stuff --------------------------------- ifeq "$(LUA)" "lua50" LUA_CFLAGS := $(shell pkg-config lua50 --cflags) LUA_LIBTOOL_D := $(shell pkg-config lualib50 --libs) LUA_LIBTOOL_S := -llua50 -llualib50 LUA_RPATH:= $(PREFIX)/lib/lua/50/ LUA_HPATH:=$(PREFIX)/include/lua50/ LUA_DPATH:=$(PREFIX)/share/doc/luacurl/ LUA_LPATH:=$(PREFIX)/lib/ #compat-5.1.[ch] are not provided in this package OBJS:= lua-curl.lo luabind.lo compat-5.1.lo endif # ------------------------- Here the Makefile -------------------------------- all: $(LIBNAME).la constants:$(CONSTANTS) doc: doc/curl.html doc/curl.html: lua-curl.luadoc cp lua-curl.luadoc doc/curl.lua $(LUADOC) -d `pwd`/doc/ `pwd`/doc/*.lua rm -f doc/*.lua doc/index.html %.lo: %.c $(LIBTOOL) --mode=compile $(CC) -c -Wall -O2 $(LUA_CFLAGS) $< # link objects to make static and dynamic libraries. The .so will be # left in "./.libs/". Note that the Lua library and its dependencies are # not called out on the link line since they are assumed to be part of # whatever our library is linked to. We want to avoid duplicate library # copies, which is a waste of space and can cause run-time problems. $(LIBNAME).la curl.so: constants $(OBJS) $(LIBTOOL) --mode=link $(CC) \ -rpath $(LUA_RPATH) -o $(LIBNAME).la \ -version-info $(VERSION_INFO) \ $(CURL_LDFLAGS) $(OBJS) ln -sf ./.libs/$(REALSO) curl.so # If all went well, we can dynamically load the module into Lua. The # following will load the library into the interpreter and call a function. test: curl.so @echo "************************* lua dynamic ***************************" $(LUA) -l curl test.lua @echo "*****************************************************************" # install static and dynamic libraries for module to global location install: $(LIBNAME).la mkdir -p $(LUA_RPATH) mkdir -p $(LUA_LPATH) $(LIBTOOL) --mode=install install $(LIBNAME).la \ $(LUA_LPATH)/$(LIBNAME).la $(LIBTOOL) --finish $(LUA_LPATH) cd $(LUA_RPATH);\ ln -s /$(subst $(DESTDIR),,$(LUA_LPATH))/$(REALSO) curl.so mkdir -p $(LUA_HPATH) $(LIBTOOL) --mode=install install lua-curl.h $(LUA_HPATH)/lua-curl.h mkdir -p $(LUA_DPATH) $(LIBTOOL) --mode=install install doc/curl.html $(LUA_DPATH)/curl.html clean: $(RM) -f *.o *.lo *.la *.so app doc/index.html doc/*.lua $(RM) -rf ./.libs/ $(RM) -f $(CONSTANTS) static-stamp dynamic-stamp $(RM) -rf win32-* dist: clean DIR=`basename $$PWD`;\ VERSION=`grep LUACURL_VERSION version.h|cut -d \" -f 2`;\ cd ..;\ cp -r $$DIR lua-curl-$$VERSION; \ tar -cvzf lua-curl_$$VERSION.orig.tar.gz \ -X $$DIR/exclude-dist lua-curl-$$VERSION;\ rm -rf lua-curl-$$VERSION # Constants genereated starting from the cURL headers: curlopt.h: $(HEADER) $(H)cat $(HEADER) | grep "^ *CINIT(" | sed "s/CINIT(/{\"OPT_/" | \ tr -s " " " " | sed "s/, /\",CURLOPTTYPE_/" | \ sed "s/, / + /" | sed "s/),/},/" > curlopt.h curl_netrcopt.h:$(HEADER) $(H)cat $(HEADER) | grep "^ *CURL_NETRC_[A-Z]*," | \ sed 's/^ *CURL_\(NETRC_[A-Z]*\),.*$$/{"\1", (int)CURL_\1},/' \ > curl_netrcopt.h curl_authopt.h:$(HEADER) $(H)cat $(HEADER) | grep "CURLAUTH_" | \ sed "s/#define *CURL/{\"/" | sed "s/ *\/\*.*\*\///" | \ sed "s/ /\",/" | sed "s/$$/},/" > curl_authopt.h curl_ftpauthopt.h:$(HEADER) $(H)cat /usr/include/curl/curl.h | grep -B10 '} curl_ftpauth' | \ grep "CURLFTPAUTH_" | \ grep -v "LAST.*never use" | \ sed "s/^ *CURL//" | sed "s/^\([^,]*\),.*$$/{\"\1\",CURL\1},/" \ > curl_ftpauthopt.h curl_ftpmethods.h:$(HEADER) $(H)cat /usr/include/curl/curl.h | grep -B10 '} curl_ftpmethod' | \ grep "CURLFTPMETHOD_" | \ grep -v "LAST.*never use" | \ sed "s/^ *CURL//" | sed "s/^\([^,]*\),.*$$/{\"\1\",CURL\1},/" \ > curl_ftpmethods.h curl_form.h: $(HEADER) $(H)cat $(HEADER) | grep "^ *CFINIT" | grep -v "CFINIT(NOTHING)" | \ sed 's/^ *CFINIT(\([^)]*\)),.*$$/{"FORM_\1",CURLFORM_\1},/' \ > curl_form.h # win32 stuff .PHONY: win32-openssl win32-openssl: make clean make constants HEADER=/usr/i586-mingw32msvc/include/curl/curl.h mkdir -p win32-openssl cd win32-openssl; unzip ../lua5_1_4_Win32_dll8_lib.zip cd win32-openssl; rm *.dll *.lib cd win32-openssl; unzip ../lua5_1_4_Win32_bin.zip i586-mingw32msvc-gcc \ -I win32-openssl/include/ \ -I . -I /usr/i586-mingw32msvc/include/ \ -c lua-curl.c -o win32-openssl/lua-curl.o i586-mingw32msvc-gcc -I . \ -I win32-openssl/include/ \ -I /usr/i586-mingw32msvc/include/ \ -c luabind.c -o win32-openssl/luabind.o i586-mingw32msvc-dlltool -e win32-openssl/exports.o -l win32-openssl/lua-curl.lib win32-openssl/*.o i586-mingw32msvc-gcc win32-openssl/*.o \ -o win32-openssl/curl.dll -shared \ -L /usr/i586-mingw32msvc/bin/ \ win32-openssl/lua5.1.dll \ -lcurl-4 for X in libcurl-4 libz; do\ cp /usr/i586-mingw32msvc/bin/$$X.dll win32-openssl;\ done cp test.lua win32-openssl rm -rf win32-openssl/*.o win32-openssl/include/ \ win32-openssl/*.lib win32-openssl/lua51.dll i586-mingw32msvc-strip win32-openssl/*.dll cp -r win32-openssl freepops-lua-curl-binary-win32-openssl zip -r freepops-lua-curl-binary-win32-openssl.zip freepops-lua-curl-binary-win32-openssl rm -rf freepops-lua-curl-binary-win32-openssl mv freepops-lua-curl-binary-win32-openssl.zip .. # eof lua-curl-0.3.0/test.lua0000644000175000017500000000007211100635242013741 0ustar tassitassiprint(curl.version()) table.foreach(package.loaded,print) lua-curl-0.3.0/luabind.c0000644000175000017500000000725211100635242014050 0ustar tassitassi/****************************************************************************** * $Id: luabind.c,v 1.4 2008/10/25 11:58:03 gareuselesinge Exp $ * This file is part of FreePOPs (http://www.freepops.org) * * This file is distributed under the terms of GNU GPL license or, at your * * option, MIT license . * ******************************************************************************/ /****************************************************************************** * File description: * hacks useful to create bindings * Notes: * * Authors: * Name ******************************************************************************/ #include #include #include #include #include "luabind.h" /****************************************************************************** * DEBUG ONLY * */ #define LINE_PREFIX "L: " static void L_printstack(lua_State* s) { int i; fprintf(stderr,"%slua stack image:\n",LINE_PREFIX); for(i=lua_gettop(s) ; i > 0 ; i-- ) { fprintf(stderr,"%sstack(%2d) : %s: ",LINE_PREFIX,i, lua_typename(s,lua_type(s,i))); switch(lua_type(s,i)){ case LUA_TSTRING: fprintf(stderr," \"%s\"\n",lua_tostring(s,i)); break; case LUA_TNUMBER: fprintf(stderr," %5.3f\n",lua_tonumber(s,i)); break; case LUA_TBOOLEAN: fprintf(stderr," %s\n", lua_toboolean(s,i)==0?"true":"false"); break; case LUA_TNIL: fprintf(stderr," nil\n"); break; default: fprintf(stderr," ??\n"); break; } } fprintf(stderr,"%sstack( 0) : --bottom--\n\n",LINE_PREFIX); } /****************************************************************************** * The error function * */ void L_error(lua_State* L, char* msg, ...){ char buffer[1024]; va_list ap; va_start(ap,msg); vsnprintf(buffer,1024,msg,ap); va_end(ap); L_printstack(L); luaL_error(L,buffer); } /****************************************************************************** * calculates the size of a table * */ int L_tablesize(lua_State* L,int n){ int i = 0; if ( !lua_istable(L,n)) L_error(L,"expecting a table, " "not a %s",lua_typename(L,lua_type(L,-1))); lua_pushnil(L); while( lua_next(L,n) != 0 ){ i++; lua_pop(L,1); } return i; } /****************************************************************************** * check number of arguments * */ void L_checknarg(lua_State* L,int n,char* msg){ if( lua_gettop(L) != n ) L_error(L,"Stack has %d values: '%s'",lua_gettop(L),msg); } /****************************************************************************** * expects a table on top and adds all t fields to this table * */ void L_openconst(lua_State* L,const struct L_const* t) { int i; for ( i = 0 ; t[i].name != NULL ; i++){ lua_pushstring(L,t[i].name); lua_pushnumber(L,(lua_Number)t[i].value); lua_settable(L,-3); } } /****************************************************************************** * expects a table on top and adds all t fields to this table * also the metatable typeshould exist */ void L_openTconst(lua_State* L,const struct L_Tuserdata* t,const char * type){ int i; for ( i = 0 ; t[i].name != NULL ; i++){ void * c; lua_pushstring(L,t[i].name); c = lua_newuserdata(L,sizeof(void*)); *(void**)c = t[i].data; luaL_getmetatable(L,type); lua_setmetatable(L,-2); lua_settable(L,-3); } } /******************************************************************************* * since there is no luaL_checklightuserdata * * */ void * L_checkludata(lua_State* L,int n){ if (! lua_islightuserdata(L,n)) L_error(L,"Argument %d is %s, expected is lightuserdata",n, lua_typename(L,lua_type(L,n))); return lua_touserdata(L,n); } lua-curl-0.3.0/doc/0000755000175000017500000000000011100635242013025 5ustar tassitassilua-curl-0.3.0/doc/curl.html0000644000175000017500000001404711100635242014666 0ustar tassitassicurl.lua

cURL bindings.

Description: read the cURL curl_easy_setopt manpage. As a convention all CURL_XXXXX and CURLXXXXX names are mapped to curl.XXXXX constants. options taking a long now take a number, options taking a string here take a string (no need to ensure the string will be available until you call perform, the bindings do this for you). Functions to write like the curl.OPT_WRITEFUNCTION and curl.OPT_HEADERFUNCTION take a string argument and a number (the string len) must return a couple, byte,server and error message . if the number of byte returned is different from the string len it is considered an error. this is an example of a callback factory:
 function build_w_cb(t)
         return function(s,len)
                   stores the received data in the table t
                 table.insert(t,s)
                   return number_of_byte_served, error_message
                   number_of_byte_served ~= len is an error
                 return len,nil
         end
 end
 
This cb factory stores all the chunks received in table t. you can have the whole file back using table.concat(t). The callback for curl.OPT_READFUNCTION takes a number, the number of the maximum amount of data that can return. Here a simple example of an infinite stream of '#':
 function build_r_cb()
      return function(n)
              local s = string.rep("#",n)
                return size_of_data,data
                size_of_data = 0 means end of data
                size_of_data must be <= n
              return string.len(s),s
      end
end
 
curl_slist are mapped to lua tables {"item1","item2",...}. For example curl.OPT_HTTPHEADER may be called in this way:
 c:setopt(curl.OPT_HTTPHEADER,{"Referer: my_home!","Dummy-field: hello"})
 
Last important case is the curl.OPT_HTTPPOST for which a special syntax is supported:
 c:setopt(curl.OPT_HTTPPOST,{

      {curl.FORM_COPYNAME,"name1",
       curl.FORM_COPYCONTENTS,"data1",
       curl.FORM_CONTENTTYPE,"Content-type: text/plain",
       curl.FORM_END }
      ,
      {curl.FORM_COPYNAME,"name2",
       curl.FORM_COPYCONTENTS,"data2",
       curl.FORM_CONTENTTYPE,"Content-type: text/plain",
       curl.FORM_END}
 })
 
And now a simple example of an HTTP GET with a proxy:
gl_b = {}
gl_h = {}

c = curl.easy_init() 
c:setopt(curl.OPT_URL,'http://tassi.web.cs.unibo.it/cgi-bin/stats.cgi')
c:setopt(curl.OPT_WRITEFUNCTION,build_w_cb(gl_b))
c:setopt(curl.OPT_HEADERFUNCTION,build_w_cb(gl_h))
c:setopt(curl.OPT_PROXY,"localhost:3000")
c:setopt(curl.OPT_PROXYUSERPWD,"ciccio:ciccio")
print("\n\t$$ performing... returns code,error $$\n")
print(c:perform())
print("\n\t$$ here you see the header, line per line $$\n")
table.foreach(gl_h,function(i,s) print(i.."= "..string.gsub(s,"\n","")) end)
print("\n\t$$ and here you see the data, after concatenation of "..
      table.getn(gl_b).." chunks $$\n")
print(table.concat(gl_b))

Functions

curl.easy_init ()

Create a curl handler.

curl.escape (s)

URLencodes the string.

curl.unescape (s)

URLdecodes the string.

curl.version ()

version.

curl.version_info ()

version informations.

perform ()

Starts curl.

setopt (opt,data)

The setopt function.



Functions

curl.easy_init ()
    Create a curl handler.

    Return Value: userdata The CURL* handler object.

curl.escape (s)

    URLencodes the string.

    Return Value: string The escaped string.

curl.unescape (s)

    URLdecodes the string.

    Return Value: string The unescaped string.

curl.version ()

    version.

    Return Value: string The version string.

curl.version_info ()

    version informations.

    Return Value: table The version struct.

perform ()

    Starts curl.

    Return Value: number,errorstring number not zero means an error.

setopt (opt,data)

    The setopt function.
    Parameters
    optnumber one of curl.OPT_*


This file was automatically generated by LuaDoc in 18 of August of 2006.lua-curl-0.3.0/version.h0000644000175000017500000000023311100635242014114 0ustar tassitassi#define LUACURL_VERSION "0.3.0" #define LUACURL_AUTHOR "Enrico Tassi " #define LUACURL_LICENSE "Dual: GPL and MIT/X" lua-curl-0.3.0/README0000644000175000017500000000175111100635242013144 0ustar tassitassiLua-cURL These are libcURL bindings for lua 5.0 and lua 5.1, the ones used in FreePOPs (see http://www.freepops.org). The newest version of the package can be found at: http://luaforge.net/projects/luacurl/ Note that the source package is the one with the -freepops suffix (since two implementations exists). They should compile cleanly using curl from version 7.9.5 to 7.11.2. It is tested against 7.15.4 and should compile with newer versions too, but no flags newer that 7.11.2 are bound. Only the libcURL easy interface is bound. See the first lines of the Makefile for some compilation flags. The following variables can be overridden: LIBNAME=liblua-curl LIBTOOL=libtool --silent --tag=CC HEADER=/usr/include/curl/curl.h PREFIX=/usr/local/ LUA=lua5.1 # use lua50 to compile for lua 5.0 LUADOC= luadoc This software is distributed under GPL or MIT license (the same as lua 5.0 and lua 5.1) at your option. No warranties. The documentation in doc/curl.html contains some examples too. lua-curl-0.3.0/lua-curl.luadoc0000644000175000017500000000757311100635242015211 0ustar tassitassi--- -- cURL bindings. read the cURL curl_easy_setopt manpage. -- As a convention all CURL_XXXXX and CURLXXXXX names are mapped to curl.XXXXX -- constants. options taking a long now take a number, options taking a string -- here take a string (no need to ensure the string will be available until -- you call perform, the bindings do this for you). Functions to write like the -- curl.OPT_WRITEFUNCTION and curl.OPT_HEADERFUNCTION take a string argument and -- a number (the string len) must return a couple, byte,server and error message-- . if the number of byte returned is different from the string len it is -- considered an error. this is an example of a callback factory:
--
-- function build_w_cb(t)
--         return function(s,len)
--                   stores the received data in the table t
--                 table.insert(t,s)
--                   return number_of_byte_served, error_message
--                   number_of_byte_served ~= len is an error
--                 return len,nil
--         end
-- end
-- 
-- This cb factory stores all the chunks received in table t. you can have the -- whole file back using table.concat(t). The callback for -- curl.OPT_READFUNCTION takes a number, the number of the maximum amount of -- data that can return. Here a simple example of an infinite stream of '#':
--
-- function build_r_cb()
--      return function(n)
--              local s = string.rep("#",n)
--                return size_of_data,data
--                size_of_data = 0 means end of data
--                size_of_data must be <= n
--              return string.len(s),s
--      end
--end
-- 
-- curl_slist are mapped to lua tables {"item1","item2",...}. For example -- curl.OPT_HTTPHEADER may be called in this way:
--
-- c:setopt(curl.OPT_HTTPHEADER,{"Referer: my_home!","Dummy-field: hello"})
-- 
-- Last important case is the curl.OPT_HTTPPOST for which a special syntax is -- supported: --
-- c:setopt(curl.OPT_HTTPPOST,{
--
--      {curl.FORM_COPYNAME,"name1",
--       curl.FORM_COPYCONTENTS,"data1",
--       curl.FORM_CONTENTTYPE,"Content-type: text/plain",
--       curl.FORM_END }
--      ,
--      {curl.FORM_COPYNAME,"name2",
--       curl.FORM_COPYCONTENTS,"data2",
--       curl.FORM_CONTENTTYPE,"Content-type: text/plain",
--       curl.FORM_END}
-- })
-- 
-- And now a simple example of an HTTP GET with a proxy:
--
--gl_b = {}
--gl_h = {}
--
--c = curl.easy_init() 
--c:setopt(curl.OPT_URL,'http://tassi.web.cs.unibo.it/cgi-bin/stats.cgi')
--c:setopt(curl.OPT_WRITEFUNCTION,build_w_cb(gl_b))
--c:setopt(curl.OPT_HEADERFUNCTION,build_w_cb(gl_h))
--c:setopt(curl.OPT_PROXY,"localhost:3000")
--c:setopt(curl.OPT_PROXYUSERPWD,"ciccio:ciccio")
--print("\n\t$$ performing... returns code,error $$\n")
--print(c:perform())
--print("\n\t$$ here you see the header, line per line $$\n")
--table.foreach(gl_h,function(i,s) print(i.."= "..string.gsub(s,"\n","")) end)
--print("\n\t$$ and here you see the data, after concatenation of "..
--      table.getn(gl_b).." chunks $$\n")
--print(table.concat(gl_b))
--
--- -- Create a curl handler. -- @return userdata The CURL* handler object. function curl.easy_init() end --- -- The setopt function. -- @param opt number one of curl.OPT_*. function setopt(opt,data) end --- -- Starts curl. -- @return number,errorstring number not zero means an error. function perform() end --- -- URLencodes the string. -- @return string The escaped string. function curl.escape(s) end --- -- URLdecodes the string. -- @return string The unescaped string. function curl.unescape(s) end --- -- version. -- @return string The version string. function curl.version() end --- -- version informations. -- @return table The version struct. function curl.version_info() end