cURL / Mailing Lists / curl-users / Single Mail

curl-users

Re: Question of using Libcurl

From: Michael Mealling <michael_at_bailey.dscga.com>
Date: Fri, 12 Jan 2001 11:15:54 -0500

On Fri, Jan 12, 2001 at 04:54:59PM +0100, Daniel Stenberg wrote:
> On Fri, 12 Jan 2001, Gandt, Eric wrote:
> 5.2 How can I receive all data into a large memory chunk?
>
> One solution to this problem could be to have a pointer to a struct that
> you pass to the callback function. You set the pointer using the
> curl_easy_setopt(CURLOPT_FILE) function. Then that pointer will be passed
> to the callback instead of a FILE * to a file:
>
> /* imaginary struct */
> struct MemoryStruct {
> char *memory;
> size_t size;
> };
>
> /* imaginary callback function */
> size_t
> WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
> {
> register int realsize = size * nmemb;
> struct MemoryStruct *mem = (struct MemoryStruct *)data;
>
> mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
> if (mem->memory) {
> memcpy(&(mem->memory[mem->size]), ptr, realsize);
> mem->size += realsize;
> mem->memory[mem->size] = 0;
> }
> return realsize;
> }

Since many of us are already using glib you can save yourself some
typing by using a GString. Here's my version which I used to post
some XML and get some back:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>

#include "cnrpengine.h" /* my stuff, you can ignore */

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
  if(g_string_append((GString *)stream, (char *) ptr) == NULL) {
     return(-1);
  } else {
     return(strlen(ptr));
  }
}

int httpxport(cnrpQuery *query, cnrpService *service, GString *output)
{
  CURL *curl_handle;
  struct curl_slist *header_list;
  char *querystring = NULL;
  cnrpServer *server = NULL;
  char errorbuffer[CURL_ERROR_SIZE];

  /* printServerUri(service); */
  if(output == NULL) { return E_FAIL; }
  if(!generateQuery(query)) { return E_FAIL; }
  querystring = query->xml_buffer->str;

  /* init the curl session */
  if((curl_handle = curl_easy_init()) == NULL) return E_FAIL;

  /* set URL to get */
  server = pickServer(service, "http");
  curl_easy_setopt(curl_handle, CURLOPT_URL, server->serveruri);

  header_list = curl_slist_append(NULL, "Content-type: text/xml");
  curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, header_list);
  curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
  curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, querystring);

  /* shut up completely */
  curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
  curl_easy_setopt(curl_handle, CURLOPT_MUTE, 1);

  /* send all data to this function */
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);

  /* pass the actually download file to this file handle */
  curl_easy_setopt(curl_handle, CURLOPT_FILE, output);

  /* take all errors and send 'em to this buffer to make sure its
     really quiet */
  curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, errorbuffer);

  /* make sure we're following redirects */
  curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION);

  /* get it! */
  curl_easy_perform(curl_handle);

  /* cleanup curl stuff */
  curl_slist_free_all(header_list);
  curl_easy_cleanup(curl_handle);

  return E_SUCCESS;
}

-MM

-- 
--------------------------------------------------------------------------------
Michael Mealling	|      Vote Libertarian!       | www.rwhois.net/michael
Sr. Research Engineer   |   www.ga.lp.org/gwinnett     | ICQ#:         14198821
Network Solutions	|          www.lp.org          |  michaelm_at_netsol.com
Received on 2001-01-12