#include "curl/curl.h" #include #include "ns.h" #include static curl_version_info_data *curlinfo; char *version = NULL; char * Version(); static int curlRead( void *ptr, size_t size, size_t nmemb, void *stream); int ns_proxy_init (Tcl_Interp *interp, void *context); int curlGet (ClientData arg, Tcl_Interp *interp, int argc, char **argv); int curlVersion (ClientData arg, Tcl_Interp *interp, int argc, char **argv); typedef struct clientData { char *data; //holder for content size_t size; // need holder for realloc } clientData; int Ns_ModuleVersion = 1; int Ns_ModuleInit (char * server, char *argv[]) { return (Ns_TclInitInterps(server,ns_proxy_init,NULL)); } int ns_proxy_init (Tcl_Interp *interp, void *context) { Tcl_CreateCommand(interp, "ns_libcurl", curlGet, NULL, NULL); Tcl_CreateCommand(interp, "ns_libcurl_version", curlVersion, NULL, NULL); return NS_OK; } int curlVersion (ClientData arg, Tcl_Interp *interp, int argc, char **argv) { if (version == NULL) { curl_global_init(CURL_GLOBAL_ALL); curlinfo = curl_version_info(CURLVERSION_NOW); version = (char *) curlinfo->version; curl_global_cleanup(); } Tcl_AppendResult(interp, version, NULL); return TCL_OK; } int curlGet (ClientData arg, Tcl_Interp *interp, int argc, char **argv) { if (argc < 1) { Tcl_AppendResult(interp, "wrong # args: should be ns_libcurl url", NULL); return TCL_ERROR; } CURL *curlhandle = NULL; struct clientData cd; cd.data = NULL; cd.size = 0; curl_global_init(CURL_GLOBAL_ALL); curlhandle = curl_easy_init(); curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION , curlRead); //overwrite conn->set.fwrite function curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, &cd); //so now void * stream is set to &cd curl_easy_setopt(curlhandle, CURLOPT_URL, argv[1]); curl_easy_perform(curlhandle); curl_easy_cleanup(curlhandle); Tcl_AppendResult(interp,cd.data,NULL); free(cd.data); memset(&cd, 0, sizeof( cd)); //curl_global_cleanup(); return TCL_OK; } static int curlRead ( void *ptr, size_t size, size_t nmemb, void *stream) { struct clientData * this_cd = (struct clientData *) stream; size_t realsize = size * nmemb; if (this_cd->data == NULL) { this_cd->data = malloc(realsize +1); } else { this_cd->data = realloc(this_cd->data, (realsize + this_cd->size +1)); } if(this_cd->data == NULL) { perror("curlRead: cannot allocate memory, insert 50c into meter please"); return 0; } memcpy(&(this_cd->data[this_cd->size]), (char *) ptr, realsize); this_cd->size += realsize; this_cd->data[this_cd->size] = 0; return realsize; } int Nslibcurl_Init (Tcl_Interp *interp) { ns_proxy_init(interp, NULL); return TCL_OK; }