[PD-dev] HTTP requests external : cURL threads ?

Alexandre Quessy listes at sourcelibre.com
Thu Jul 20 23:27:25 CEST 2006


On 6/22/06, Hans-Christoph Steiner <hans at eds.org> wrote:
> As for crashes, since libcurl wants to use a call back function, you will
> need have a separate thread, AFAIK.  That separate thread could just wait
> for libcurl to call the callback, then write data to a data structure.  The
> Pd object would then just check the data structure for the status of things.
>  externals/olafmatt/hidin is a example of how to do the threading, even tho
> its Windows only object, the threading method will be the same.


Interesting ! Would that shared data structure be a global variable ?
If so, could I make it unique so that we can create multiple instances
of that pd object ?

I will look at that object's code. Thanks !

Sorry for replying late... :)


-- 
Alexandre Quessy
http://alexandre.quessy.net




>
>
>
> On Jun 19, 2006, at 9:18 AM, Alexandre Quessy wrote:
>
> Hi,
>
> I am working on a simple external to do HTTP requests from PD. The idea is
> to implement a simple way to send and receive simple data to a web server.
> This is intended to work together with a set of classes that will interpret
> the GET variables as key and values pairs where the values can be similar to
> FUDI protocol messages. The web page would then answer with a FUDI message
> or so. I don't use Python because I want it to be very fast, totally
> portable and easy to install. (I also agree with Hans regarding small tools
> to make a constellation of low level objects)
>
> Here are my bugs : perhaps I am not very good yet with strings in C, but I
> have several errors when I try to execute this code from within PD as an
> external. Well, when I get malloc errors, it must be only about memory size
> arithmetics, but when it gets into segmentation faults, I was just wondering
> if it could be because cURL starts a new thread. I think that thread are not
> much appropriate in PD's context. Do you think this is the problem, or I am
> just still a bit bad with memory maths ?
>
> Also, if you have ideas about this external, please don't hesitate. I think
> I will rename it to http, as it is not intended in downloading whole files,
> but just for simple HTTP requests.
>
> See below for the current code, the makefile and one of the errors it
> creates.
>
> Alexandre Quessy
> http://alexandre.quessy.net
>
> ============================= error when using it ====================
> t=0&ie
> pd wget-help.pd
> STACK_END old=0xbf9e5ffc; new=0xbf9efffc
> PDP: pure data packet
> PDP: version 0.12.4
> * About to connect() to alexandre.quessy.net port 80
> *   Trying 64.15.134.165... * connected
> * Connected to alexandre.quessy.net (64.15.134.165) port 80
> > GET /pd/curlme.php?asd=qwe+123 HTTP/1.1
> User-Agent: Pure Data
> Host: alexandre.quessy.net
> Accept: */*
>
> < HTTP/1.1 200 OK
> < Date: Mon, 19 Jun 2006 16:03:44 GMT
> < Server: Apache
> < X-Powered-By: PHP/4.3.10-16
> < Connection: close
> < Transfer-Encoding: chunked
> < Content-Type: text/html
> * Closing connection #0
> socket receive error: Connection reset by peer (104)
> Erreur de segmentation
>
> ================== makefile
> ====================================
>
>  all: wget.pd_linux
>      @echo "making wget"
>
>  wget.pd_linux: wget.c
>      gcc -DPD -O2 -funroll-loops -fomit-frame-pointer \
>        -Wall -W -Wshadow -Wstrict-prototypes \
>        -Wno-unused -Wno-parentheses -Wno-switch -o wget.o -c wget.c
>      ld -export_dynamic -shared -o wget.pd_linux wget.o -lcurl -lc -lm
>      strip --strip-unneeded wget.pd_linux
>      rm wget.o
>
>
>
> ================== code : wget.c
> ================================
>
> /**
>  * [wget] is a Pure Data object for simple HTTP requests.
>  *
>  * @url http://alexandre.quessy.net/
>  * @author Alexandre Quessy <alexandre at quessy.net>
>  * @license GNU General Public License 2006
>  */
> #define PDWGET_VERSION "0.1.0"
>
> /* PD includes */
> #include "m_pd.h"
>
> /* cURL and standard C libraries */
> #include <curl/curl.h>
> #include <string.h>
> #include <stdlib.h>
>
> /* Download callback function prototype */
> size_t wget_callBack(void *ptr, size_t size, size_t nmemb, void *x);
>
> /**
>  * variables of the pd object
>  */
> typedef struct wget {
>   t_object x_ob; /* The instance. Contains inlets and outlets */
>   t_outlet *x_outlet0; /* result string */
>   t_outlet *x_outlet1; /* HTTP error codes */
> } t_wget;
>
>
>
> /**
>  * HTTP request.
>  */
> void wget_request(t_wget *x, t_symbol *s, int argc, t_atom *argv) {
>     post("wget : called request.");
>
> //curl_global_init(CURL_GLOBAL_NOTHING);//CURL_GLOBAL_ALL
>
>     //t_symbol *sym_tmp = atom_getsymbol(&argv[0]);
>     if (argc < 1) {
>         post("wget : Error : needs arguments.");
>     } else {
>     t_symbol *sym_tmp = atom_getsymbolarg(0, argc, argv);
>         char *url = sym_tmp->s_name;
>
>     post("wget : requesting : %s", url);
>
>     /* cURL context */
>     CURL *pContext = curl_easy_init();
>     if (pContext == NULL) {
>         post("wget : Error :  Null cURL handle.");
>     } else {
>         /* cURL options */
>         CURLcode pCode = curl_easy_setopt(pContext, CURLOPT_URL, url);
>         curl_easy_setopt(pContext, CURLOPT_WRITEFUNCTION, wget_callBack,
> (void *) x);
>         curl_easy_setopt(pContext, CURLOPT_VERBOSE, 1);
>         curl_easy_setopt(pContext, CURLOPT_HEADER, 0);
>         curl_easy_setopt(pContext, CURLOPT_NOPROGRESS, 1);
>         curl_easy_setopt(pContext, CURLOPT_USERAGENT, "Pure Data");
>         curl_easy_setopt(pContext, CURLOPT_NOSIGNAL, 1);
>         curl_easy_setopt(pContext, CURLOPT_TIMEOUT, (long) 5);
>
>         /* cURL performing */
>         post("wget : Performing the request.");
>         const CURLcode result = curl_easy_perform(pContext);
>         if(CURLE_OK != result) {
>             post("wget : Error from cURL: %s", curl_easy_strerror(result));
>         } else {
>
>             /* HTTP code */
>             long lHttpCode;
>             curl_easy_getinfo(pContext, CURLINFO_RESPONSE_CODE, &lHttpCode);
>             post("wget : HTTP response code: %ld ", lHttpCode);
>             //outlet_float(x->x_outlet1, (float) lHttpCode);
>         }
>     }
>
>     post("[wget] cleaning up...");
>     /* cURL cleanup */
>     curl_easy_cleanup(pContext);
>     post("[wget] Local cleaned up.");
>     //curl_global_cleanup();
>     post("[wget] Global cleaned up.");
>     //outlet_list(x->x_outlet0, gensym("A_FLOAT"), numCols+1, &atoms); //
> &atoms ??
>     } // else
> }
>
> /**
>  * The representation of the class in PD.
>  */
> t_class *wget_class;
>
> /**
>  * constructor
>  */
> void *wget_new(t_symbol *selector, int argc, t_atom *argv) {
>     post("wget : creating a new object.");
>     t_wget *x = (t_wget *) pd_new(wget_class);
>     x->x_outlet0 = outlet_new(&x->x_ob, gensym("list"));
>     x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
>     return (void *)x;
> }
>
> /**
>  * setup
>  */
> void wget_setup(void) {
>     curl_global_init(CURL_GLOBAL_NOTHING);
>     wget_class = class_new(gensym("wget"), (t_newmethod) wget_new, 0,
> sizeof(t_wget), 0, A_GIMME, 0);
>     class_addmethod(wget_class, (t_method)wget_request, gensym("request"),
> A_GIMME, 0);
>
>
> post("----------------------------------------------------");
>     post(" [wget] %s (c) GPL Copyleft 2006 Alexandre Quessy",
> PDWGET_VERSION);
>     post(" Simple HTTP requests for Pure Data.");
>
> post("----------------------------------------------------");
> }
>
> /**
>  * Callback implementation
>  */
> size_t wget_callBack(void *ptr, size_t size, size_t nmemb, void *x) {
>     size_t totalSize = nmemb * size;
>     char *dest = malloc(totalSize + 1); //(sizeof(char))
>     strcpy(dest, (char *) ptr);
>     post("[wget] : Getting data.");
>     dest[totalSize] = '\0';
>     post("result :");
>     post("===============================");
>     post("%s", dest);
>     post("===============================");
>
>     //outlet_symbol(((t_wget *)x)->x_outlet0, gensym(dest));
>     //free(dest);
>     return(totalSize);
> }
>
>
>
>
>
>
> _______________________________________________
> PD-dev mailing list
> PD-dev at iem.at
> http://lists.puredata.info/listinfo/pd-dev
>
>
> ------------------------------------------------------------------------
>
> News is what people want to keep hidden and everything else is publicity.
>       - Bill Moyers
>
>




More information about the Pd-dev mailing list