#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "INLINE.h" #include #include static size_t my_curl_write(char *buffer, size_t size, size_t nitems, void *response) { sv_catpvn((SV *)(response), buffer, nitems); return nitems; } SV *new(char* class) { SV *obj_ref, *obj; CURL *curl = NULL; /* initialize curl */ curl = curl_easy_init(); if (! curl) croak("Could not initialize cURL"); curl_easy_setopt(curl, CURLOPT_MUTE, 1); /* Apache's modsecurity requires a user agent string to be set */ curl_easy_setopt(curl, CURLOPT_USERAGENT, "OME::Util::cURL"); /* bless it into the class */ obj_ref = newSV(0); sv_setref_pv(obj_ref, class, (void*) curl); SvREADONLY_on(obj_ref); return (obj_ref); } SV *POST (SV *obj, char *url, SV *aref) { CURL *curl = (CURL *)( SvIV(SvRV(obj)) ); SV *response=NULL; struct curl_httppost *post=NULL; struct curl_httppost *last=NULL; HV *param=NULL; I32 retlen=0; SV *item=NULL, *uploadRef=NULL; char *name=NULL, *contents=NULL, *uploadName=NULL, *uploadFile=NULL; size_t uploadSize; FILE *outfile=NULL; if (! curl) croak("Calling POST on an unblessed reference"); /* Check the parameters */ if (! SvROK(aref) || SvTYPE(SvRV(aref))!= SVt_PVHV) croak("aref is not a HASH reference"); param = (HV*)SvRV(aref); /* Iterate over the parameter hash */ hv_iterinit (param); item = hv_iternextsv(param, &name, &retlen); while (item) { if ( strcmp (name,"File") && strcmp (name,"Pixels") && strcmp (name,"__file") ) { /* This is not an upload parameter (File or Pixels)*/ contents = SvPV_nolen(item); curl_formadd(&post, &last, CURLFORM_COPYNAME, name, CURLFORM_COPYCONTENTS, contents, CURLFORM_END); } else if (! strcmp (name,"__file") ) { outfile = fopen (SvPV_nolen(item),"w+"); if (!outfile) croak("could not open specified output file"); } else if ( SvROK(item) ) { /* File or Pixels with a reference means we upload the buffer refered to */ uploadName = name; uploadRef = (SV*) SvRV(item); } else if ( SvPOK (item) ) { /* File or Pixels with a scalar means we upload the file */ uploadName = name; uploadFile = SvPV_nolen(item); } /* get the next parameter */ item = hv_iternextsv(param, &name, &retlen); } /* Add the file upload at the end */ if (uploadFile) { curl_formadd(&post, &last, CURLFORM_COPYNAME, uploadName, CURLFORM_FILE, uploadFile, CURLFORM_END); } else if (uploadRef) { /* upload buffer */ curl_formadd(&post, &last, CURLFORM_COPYNAME, uploadName, CURLFORM_BUFFER, "data", CURLFORM_BUFFERPTR, SvPVX(uploadRef), CURLFORM_BUFFERLENGTH, SvLEN (uploadRef), CURLFORM_END); } /* Set the curl form info */ curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); /* Make a new SV for our response */ response = newSVpvf(""); if (! outfile) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_curl_write); curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); } else { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); } curl_easy_perform(curl); /* free the post data */ curl_formfree(post); if (outfile) { fclose (outfile); outfile = NULL; } return (response); } SV *GET (SV *obj, char *url) { CURL *curl = (CURL *)( SvIV(SvRV(obj)) ); SV *response=NULL; if (! curl) croak("Calling GET on an unblessed reference"); /* Set the curl options */ curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); /* Make a new SV for our response */ response = newSVpvf(""); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_curl_write); curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); curl_easy_perform(curl); return (response); } void GET_file (SV *obj, char *url, char *file) { CURL *curl = (CURL *)( SvIV(SvRV(obj)) ); SV *response=NULL; FILE *outfile=NULL; if (! curl) croak("Calling GET_file on an unblessed reference"); if ( file && strlen (file) ) { outfile = fopen (file,"w+"); if (!outfile) croak("could not open specified output file"); } /* Set the curl options */ curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); curl_easy_perform(curl); /* cleanup */ fclose (outfile); outfile = NULL; } SV *status (SV *obj) { CURL *curl = (CURL *)( SvIV(SvRV(obj)) ); long response_code; if (! curl) croak("Calling status on an unblessed reference"); curl_easy_getinfo (curl,CURLINFO_HTTP_CODE,&response_code); return ( newSViv(response_code) ); } void DESTROY (SV *obj) { CURL *curl = (CURL *)( SvIV(SvRV(obj)) ); if (curl) { curl_easy_cleanup(curl); } } MODULE = OME::Util::cURL_79e0 PACKAGE = OME::Util::cURL PROTOTYPES: DISABLE SV * new (class) char * class SV * POST (obj, url, aref) SV * obj char * url SV * aref SV * GET (obj, url) SV * obj char * url void GET_file (obj, url, file) SV * obj char * url char * file PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; GET_file(obj, url, file); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ SV * status (obj) SV * obj void DESTROY (obj) SV * obj PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; DESTROY(obj); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */