cURL / Mailing Lists / curl-library / Single Mail

curl-library

RE: Using curl_eay_getinfo when msg->data.result == CURLE_OK

From: Jeff Pohlmeyer <yetanothergeek_at_yahoo.com>
Date: Thu, 8 Jul 2004 04:38:21 -0700 (PDT)

> what is actually happening, is that when the curl message 'cm' has a
> message CURLMSG_DONE it tries to obtain what type of file has just been
> downloaded. it's not actually returning anything other than NULL from
> this curl_easy_getinfo() function. I'm wondering why not and the value
> I get it always unknown/binary.

Libcurl tries to obtain this info from the content-type header, but not all
servers provide this information. If there is no content-type header, then
libcurl just returns NULL for CURLINFO_CONTENT_TYPE.

Here is a quick-and dirty example of using libmagic to get what you need.
( If you have "file --version" >= 4.0 then you should have libmagic. )

Be sure to pass -lmagic to the linker...

[---------------]

#include <stdio.h>
#include <magic.h>
#include <curl/curl.h>

size_t write_cb (char *buffer, size_t size, size_t nitems, void *outstream)
{
  const char* mimetype = magic_buffer((magic_t) outstream, buffer, size*nitems);
  if (mimetype) {
    printf("%s\n", mimetype);
  } else {
    fprintf(stderr, "Could not determine mime type\n");
  }
  /*
     For a "real" program, you would want to process the
     char *buffer, and return (size*nitems) to continue.
     Here I am just bailing out on the first chunk...
  */
  return 0;
}

int main(int argc, char**argv)
{
  CURL *curl;
  CURLcode rv;
  magic_t magic;
  char err[CURL_ERROR_SIZE];

  if ( 2 == argc ) {
    curl = curl_easy_init();
    if ( curl ) {
      curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, err);
      curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
      curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
      magic = magic_open(MAGIC_MIME);
      magic_load(magic, NULL);
      /*
        Here I am passing the magic_t pointer straight into
        the write callback. You would probably want to make
        it a struct field or global for a "real" application.
      */
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) magic);
      rv = curl_easy_perform(curl);
      switch (rv) {
        case CURLE_OK:
          fprintf(stderr, "No Data!\n");
          return 1;
        case CURLE_WRITE_ERROR:
          return 0;
        default:
          fprintf(stderr, "%s\n", err);
          return rv;
      }
    } else {
      fprintf(stderr, "Failed to initialize libcurl.\n");
      return 1;
    }
  } else {
    fprintf(stderr, "Usage: %s <url>\n", argv[0]);
    return 0;
  }
}

[---------------]

As another option, I think it's also possible
to do something similar with GnomeVFS

 - Jeff
 

                
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail
Received on 2004-07-08