#include "tlang.h" #if defined(USE_NETWORK) && defined(USE_CURL) #include #include 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;iitems[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