cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Curl::easy issue with header callback

From: Cris Bailiff <c.bailiff+curl_at_awayweb.com>
Date: Thu, 10 Oct 2002 09:28:31 +1000

Kalyan,

I've posted your question and my reply to the libcurl list, so that others
with the same question can find the answer in future:

On Thu, 10 Oct 2002 04:36, Kalyan Varma wrote:
> hello there,
> I have been using your Curl::easy module and ran into an issue.
> Whenever I do $curl->perform(); this prints out the HTTP headers to stdio.
> Any way to get around this ??

Yes. You need to understand a little about how the curl library performs it's
output. By default all output (headers and body) goes to STDOUT. You can ask
libcurl to send output elsewhere, either by providing a new file handle with
CURLOPT_FILE (for the body) and CURLOPT_WRITEHEADER (for the headers) or you
can ask curl to call ('callback') your own subroutine instead, where you can
do what you like with the data. If you choose to call your own subroutine,
then the value of CURLOPT_FILE or CURLOPT_WRITEHEADER is passed to that
subroutine, for it to use as it pleases (they don't have to be file handles).

You tell libcurl to call your routine by using CURLOPT_WRITEFUNCTION (for the
body) or CURLOPT_HEADERFUNCTION (for the headers). In the example you used,
only the CURLOPT_WRITEFUNCTION is given, so the header data stilll goes to
'stdout'.

The 'body callback' routine here actually 'generic' - it is fine as a header
callback as well, and will put the data into the array defined by '$context',
which can be different for each type of call. So, you can get the headers in
another array:

> sub get_page {
> my ($url) = @_;
> my $curl= Curl::easy->new() or die "curl init failed!\n";
> $curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
> my @myheaders=("User-Agent: Test Agent");
> $curl->setopt(CURLOPT_HTTPHEADER, \@myheaders);
> $curl->setopt(CURLOPT_URL, $url);
>
 
     sub callback { # better name
> my ($chunk,$context)=@_;
> push @{$context}, $chunk;
> return length($chunk); # OK
> }

     $curl->setopt(CURLOPT_WRITEFUNCTION, \&callback);

Set the header function here:

       $curl->setopt(CURLOPT_HEADERFUNCTION,\&callback);

> my @body;
> $curl->setopt(CURLOPT_FILE, \@body);

Have the headers put in their own array:
       my @headers;
       $curl->setopt(CURLOPT_WRITEHEADER,\@headers); # reference to headers

> $curl->perform(); <--- HTTP headers printed here
>
> my $data = join("",@body);

Now your headers are in @headers.

> return $data;
>
> }

If you don't want the headers (I'm sure you will do), you could just use an
'empty' callback routine, and no extra array:

 $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($chunk) } ); # do
nothing

(The subroutine still needs to return the length of the data 'consumed', to
signal to libcurl that it worked OK).

Cris

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
Received on 2002-10-10