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

Computer Science and Physics major at Saint Michael's College. Lead developer + project coordinator 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.