cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Effective URL different if CURLOPT_NOBODY is set to true

From: Jeff Pohlmeyer <yetanothergeek_at_gmail.com>
Date: Wed, 18 Mar 2009 08:16:15 -0500

On Mar 18, 2009, yetanothergeek_at_gmail.com wrote:

> ...using CURLOPT_HEADERFUNCTION
> ...when (size*nmemb)==2
> ...abort the transfer.

Err, that is not quite right, sorry.

You should only cancel the transfer after a set of headers
that *does not* contain a location header.

That gets a bit more complicated, maybe it's easier to explain
with an example:

/***************/

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

#define TRUE 1
#define FALSE 0

static int following=FALSE;

/* Our header callback */
size_t hdr_cb( void *hdr, size_t size, size_t nmemb, void *unused)
{
  size_t rv=size*nmemb;
  if (rv==2) { /* The end of this set of headers */
    if (following) {
      /* If we are following, reset the flag and carry on */
      following=FALSE;
    } else { /* Cancel the transfer */
      return 0;
    }
  } else {
    /* Check to see if we should keep going */
    if (strncasecmp(hdr, "Location:",9)==0) {
      following=TRUE;
    }
  }
  return rv;
}

int main(int argc, char*argv[])
{
  CURL*curl=curl_easy_init();
  curl_easy_setopt(curl,CURLOPT_URL,argv[1]);
  curl_easy_setopt(curl,CURLOPT_HEADERFUNCTION,hdr_cb);
  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
  CURLcode rv=curl_easy_perform(curl);
  char*eff_url=NULL;
  curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &eff_url);
  printf("%s\n", eff_url);
  curl_easy_cleanup(curl);
  return rv==CURLE_WRITE_ERROR?0:rv;
}

/***************/

It would actually be simpler to use a CURLOPT_WRITEFUNCTION
and abort on the very first chunk of data it receives, but
that would require downloading a few extra bytes each time.

- Jeff
Received on 2009-03-18