tlang-c/libtlang/src/curl.c

164 lines
5.7 KiB
C

#include "tlang.h"
#if defined(USE_NETWORK) && defined(USE_CURL)
#include <curl/curl.h>
#include <curl/easy.h>
typedef struct
{
CURL* curl;
dict_t* dict;
bool hasWriteFunction;
runtime_t* rt;
} curl_ctx;
tobject_t* __net_curl_perform_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
curl_ctx* curl = (curl_ctx*)ptr;
return tobject_number(rt,(double)curl_easy_perform(curl->curl));
}
tobject_t* __net_curl_seturl_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length == 1 && args->items[0]->type == tstring)
{
curl_ctx* curl = (curl_ctx*)ptr;
char* url = string_dupp(args->items[0]->data.string);
curl_easy_setopt(curl->curl,CURLOPT_URL,url);
free(url);
}
return tobject_basic(rt,tnull);
}
void __net_curl_free(tobject_t* obj)
{
curl_ctx* curl = (curl_ctx*)obj->ptr_data;
curl_easy_cleanup(curl->curl);
dict_free(curl->dict);
free(curl);
}
extern bool tobject_write_call(tobject_t* f,runtime_t* rt,void* ptr,int64_t len);
size_t __curl_writefn(char* ptr,size_t size,size_t nmemb,void* userdata)
{
curl_ctx* ctx2 = (curl_ctx*)userdata;
bool retVal = false; //need to set to true at end
if(ctx2->hasWriteFunction && dict_haskey(ctx2->dict,"writefunction"))
{
tobject_t* write_function = dict_getkvp(ctx2->dict,"writefunction")->value;
if(write_function != NULL && (write_function->type == tinternalmethod || write_function->type == texternalmethod))
{
retVal = tobject_write_call(write_function,ctx2->rt,ptr,size * nmemb);
}
}
return retVal ? size * nmemb : 0;
}
tobject_t* __net_curl_setwritefunction_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length == 1 && args->items[0]->type == tinternalmethod || args->items[0]->type == texternalmethod)
{
curl_ctx* ctx2 = (curl_ctx*)ptr;
if(!ctx2->hasWriteFunction)
{
curl_easy_setopt(ctx2->curl,CURLOPT_WRITEFUNCTION,__curl_writefn);
curl_easy_setopt(ctx2->curl,CURLOPT_WRITEDATA,ctx2);
ctx2->hasWriteFunction=true;
}
kvp_t kvp;
kvp.key = "writefunction";
kvp.value = args->items[0];
dict_setkvp(ctx2->dict,kvp);
}
return tobject_basic(rt,tnull);
}
tobject_t* __Net_curl_setfollowlocation_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length > 0)
{
curl_ctx* ctx2 = (curl_ctx*)ptr;
long fredirect=0;
if( args->items[0]->type == tbool)
{
fredirect = args->items[0]->data.boolean ? 1 : 0;
}
if(args->items[0]->type == tnumber)
{
fredirect = (long)args->items[0]->data.number;
}
curl_easy_setopt(ctx2->curl, CURLOPT_FOLLOWLOCATION, fredirect);
}
return tobject_basic(rt,tnull);
}
tobject_t* __net_curl_setpostfields_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length > 0 && args->items[0]->type == tstring)
{
curl_ctx* ctx2 = (curl_ctx*)ptr;
char* meth = string_dupp(args->items[0]->data.string);
curl_easy_setopt(ctx2->curl, CURLOPT_POSTFIELDS, meth);
}
return tobject_basic(rt,tnull);
}
tobject_t* __net_curl_setmethod_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length > 0 && args->items[0]->type == tstring)
{
curl_ctx* ctx2 = (curl_ctx*)ptr;
char* meth = string_dupp(args->items[0]->data.string);
curl_easy_setopt(ctx2->curl, CURLOPT_CUSTOMREQUEST, meth);
free(meth);
}
return tobject_basic(rt,tnull);
}
tobject_t* __net_curl_setrequestheaders_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
if(args->length > 0 && args->items[0]->type == tlist)
{
curl_ctx* ctx2 = (curl_ctx*)ptr;
struct curl_slist *headers = NULL;
int i;
for(i=0;i<args->items[0]->data.list.length;i++)
{
string_t* str=tobject_tostring(rt->globals,args->items[0]->data.list.items[i]);
char* data= string_dupp(str);
string_free(str);
headers=curl_slist_append(headers,data);
free(data);
}
curl_easy_setopt(ctx2->curl, CURLOPT_HTTPHEADER, headers);
}
return tobject_basic(rt,tnull);
}
tobject_t* __net_curl_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
{
CURL* curl = curl_easy_init();
if(curl != NULL){
tobject_t* ctx = tobject_create(rt);
ctx->type = tdict;
ctx->data.dict = dict_create();
ctx->free = __net_curl_free;
curl_ctx* ctx2 = (curl_ctx*)malloc(sizeof(curl_ctx));
ctx2->rt=rt;
ctx2->curl=curl;
ctx2->dict = dict_create();
ctx2->hasWriteFunction = false;
ctx->ptr_data = ctx2;
runtime_create_method_on_object(ctx,"seturl",rt,ctx2,__net_curl_seturl_external_method,NULL);
runtime_create_method_on_object(ctx,"perform",rt,ctx2,__net_curl_perform_external_method,NULL);
runtime_create_method_on_object(ctx,"setwritefunction",rt,ctx2,__net_curl_setwritefunction_external_method,NULL);
runtime_create_method_on_object(ctx,"setmethod",rt,ctx2,__net_curl_setmethod_external_method,NULL);
runtime_create_method_on_object(ctx,"setpostfields",rt,ctx2,__net_curl_setpostfields_external_method,NULL);
runtime_create_method_on_object(ctx,"setrequestheaders",rt,ctx2,__net_curl_setrequestheaders_external_method,NULL);
runtime_create_method_on_object(ctx,"setfollowlocation",rt,ctx2,__Net_curl_setfollowlocation_external_method,NULL);
return ctx;
}
return tobject_basic(rt,tnull);
}
void runtime_register_curl(runtime_t* rt,dict_t* net)
{
runtime_create_method_on_dict(net,"curl",rt,NULL,__net_curl_external_method,NULL);
}
#endif