Game Development Community

crashing and burning (in the code sense, not the graphical sense...)

by Thomas -elfprince13- Dickerson · in Torque Game Engine · 06/03/2009 (8:43 pm) · 5 replies

I followed Fyodor's instructions for libcurl integration, and get everything set up and working correctly. Unfortunately the code he wrote doesn't allow for POSTing data over http, so I set out to write my own to handle that eventuality. I got everything set up and compiling, however when I try to call curl_formadd everything crashes and burns. Here's the code that I was trying to use:

void SimCurl::addPostField(const char *fieldname, const char *fielddata){
   post = true;
   struct curl_httppost *formpost;    //added by thomas
   struct curl_httppost *lastptr;        //added by thomas
   curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, fieldname, CURLFORM_COPYCONTENTS, fielddata, CURLFORM_END);
}


and the reference for for curl_formadd(), curl.haxx.se/libcurl/c/curl_formadd.html.

I'm relatively new to C++, so just to double check that I wasn't passing a pointer reference instead of data, or anything like that, I tried this code instead.

void SimCurl::addPostField(const char *fieldname, const char *fielddata){
   post = true;
   struct curl_httppost *formpost;    //added by thomas
   struct curl_httppost *lastptr;        //added by thomas
   curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME,  "username", CURLFORM_COPYCONTENTS, "elfprince13", CURLFORM_END);
}

Still no luck. So just to make sure that it really was curl_formadd causing the difficulties (as seemed to be the case based on the crash reports being generated by OS X's crash reporter), I tried this code instead:

void SimCurl::addPostField(const char *fieldname, const char *fielddata){
   post = true;
   Con::printf("%s=%s",fieldname,fielddata);
   struct curl_httppost *formpost;    //added by thomas
   struct curl_httppost *lastptr;        //added by thomas
}


Works like a charm. Anybody have ideas as to what I'm doing wrong here?

About the author

C.S. PhD student at Brown University. Project lead for FreeBuild. Administrator, Cemetech tech community. Webmaster for the Village2Village Projects and the Vermont Sustainable Heating Initiative.


#1
06/04/2009 (10:45 am)
hm, we're using our own integration of libCurl, but i see a routine which looks very similar to the code you've posted, so it might be a problem outside the routine you've got there.

here's our example:
bool CURLPostFileUploader::setKeyValue(const char *key, const char *value)
{
   // check if we have already started
   // this is just a sanity check to make sure we're not trying to
   // change the contents of the post after it's already been sent.
   if (CheckForStart(__FUNCTION__))
   {
      return false;
   }

   curl_formadd(&mFirstItem, &mLastItem,
      CURLFORM_COPYNAME, key,
      CURLFORM_COPYCONTENTS, value, 
      CURLFORM_END);

   return true;
}
#2
06/04/2009 (10:48 am)
wait, thomas,
try initializing formpost and lastptr to NULL.
curl.haxx.se/libcurl/c/curl_formadd.html
#3
06/08/2009 (11:16 pm)
Orion, thanks for the responses, I didn't see your second one, however I do initialize them to NULL in SimCurl::initialize. If I set them to NULL in every function call I wouldn't be able to add multiple headers, and would leak memory as well, unless I'm completely misunderstanding how this works.
#4
06/08/2009 (11:51 pm)
heya -
maybe i'm misreading the code, but eg in your first snippet it looks to me like formpost is a local variable, created within the scope of addPostField(). if formpost is a member variable of the class, you shouldn't re-declare it in the local scope. which means it's going to be non-NULL and pointing to some random memory location when it's passed to curl_formadd().

you might want something like:
class SimCurl
{
   // blah blah
   struct curl_httppost *mFormPost;   
}

void SimCurl::initialize()
{
   mFormPost = NULL;
}

void SimCurl::addPostField()
{
   curl_formadd(&mFormPost, etc);
}

#5
06/09/2009 (8:42 am)
BAH. you're right. I'm going to go test that now, but I'm guessing that'll do the trick.

[edit]

:) Well, I had a couple other things that needed changing (moving the =NULL assignments and the garbage collection into the constructor and destructor, rather than initialize and deinitialize), but that was the root of it. Thanks for the help.