This file is indexed.

/usr/share/perl5/Furl.pm is in libfurl-perl 3.05-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
package Furl;
use strict;
use warnings;
use utf8;
use Furl::HTTP;
use Furl::Request;
use Furl::Response;
use Carp ();
our $VERSION = '3.05';

use 5.008001;

$Carp::Internal{+__PACKAGE__} = 1;

sub new {
    my $class = shift;
    bless \(Furl::HTTP->new(header_format => Furl::HTTP::HEADERS_AS_HASHREF(), @_)), $class;
}

sub get {
    my ( $self, $url, $headers ) = @_;
    $self->request(
        method  => 'GET',
        url     => $url,
        headers => $headers
    );
}

sub head {
    my ( $self, $url, $headers ) = @_;
    $self->request(
        method  => 'HEAD',
        url     => $url,
        headers => $headers
    );
}

sub post {
    my ( $self, $url, $headers, $content ) = @_;
    $self->request(
        method  => 'POST',
        url     => $url,
        headers => $headers,
        content => $content
    );
}

sub put {
    my ( $self, $url, $headers, $content ) = @_;
    $self->request(
        method  => 'PUT',
        url     => $url,
        headers => $headers,
        content => $content
    );
}

sub delete {
    my ( $self, $url, $headers ) = @_;
    $self->request(
        method  => 'DELETE',
        url     => $url,
        headers => $headers
    );
}


sub agent {
    @_ == 2 ? ${$_[0]}->agent($_[1]) : ${$_[0]}->agent;
}

sub env_proxy {
    my $self = shift;
    $$self->env_proxy;
}

sub request {
    my $self = shift;

    my %args;
    if (@_ % 2 == 0) {
        %args = @_;
    } else {
        # convert HTTP::Request to hash for Furl::HTTP.

        my $req = shift;
        %args = @_;
        my $req_headers= $req->headers;
        $req_headers->remove_header('Host'); # suppress duplicate Host header
        my $headers = +[
            map {
                my $k = $_;
                map { ( $k => $_ ) } $req_headers->header($_);
            } $req_headers->header_field_names
        ];

        $args{url}     = $req->uri;
        $args{method}  = $req->method;
        $args{content} = $req->content;
        $args{headers} = $headers;
    }

    my $cookie_jar = ${$self}->{cookie_jar};

    if ($cookie_jar) {
        my $url;
        if ($args{url}) {
            $url = $args{url};
        } else {
            $url = join(
                '',
                $args{scheme},
                '://',
                $args{host},
                (exists($args{port}) ? ":$args{port}" : ()),
                exists($args{path_query}) ? $args{path_query} : '/',
            );
        }
        push @{$args{headers}}, 'Cookie' => $cookie_jar->cookie_header($url);
    }

    my (
        $res_minor_version,
        $res_status,
        $res_msg,
        $res_headers,
        $res_content,
        $captured_req_headers,
        $captured_req_content,
        $captured_res_headers,
        $captured_res_content,
        $request_info,
        ) = ${$self}->request(%args);

    my $res = Furl::Response->new($res_minor_version, $res_status, $res_msg, $res_headers, $res_content);
    $res->set_request_info(\%args, $captured_req_headers, $captured_req_content);

    if ($cookie_jar) {
        my ($scheme, $username, $password, $host, $port, $path_query) = @$request_info;
        my $req_url = join(
            '',
            $scheme,
            '://',
            (defined($username) && defined($password) ? "${username}:${password}@" : ()),
            "$host:${port}${path_query}",
        );
        for my $cookie ($res->header('Set-Cookie')) {
            # Do not use $args{url} as a url. Because the server may redirected.
            $cookie_jar->add($req_url, $cookie);
        }
    }

    return $res;
}

1;
__END__

=encoding utf8

=head1 NAME

Furl - Lightning-fast URL fetcher

=head1 SYNOPSIS

    use Furl;

    my $furl = Furl->new(
        agent   => 'MyGreatUA/2.0',
        timeout => 10,
    );

    my $res = $furl->get('http://example.com/');
    die $res->status_line unless $res->is_success;
    print $res->content;

    my $res = $furl->post(
        'http://example.com/', # URL
        [...],                 # headers
        [ foo => 'bar' ],      # form data (HashRef/FileHandle are also okay)
    );

    # Accept-Encoding is supported but optional
    $furl = Furl->new(
        headers => [ 'Accept-Encoding' => 'gzip' ],
    );
    my $body = $furl->get('http://example.com/some/compressed');

=head1 DESCRIPTION

Furl is yet another HTTP client library. LWP is the de facto standard HTTP
client for Perl 5, but it is too slow for some critical jobs, and too complex
for weekend hacking. Furl resolves these issues. Enjoy it!

=head1 INTERFACE

=head2 Class Methods

=head3 C<< Furl->new(%args | \%args) :Furl >>

Creates and returns a new Furl client with I<%args>. Dies on errors.

I<%args> might be:

=over

=item agent :Str = "Furl/$VERSION"

=item timeout :Int = 10

=item max_redirects :Int = 7

=item capture_request :Bool = false

If this parameter is true, L<Furl::HTTP> captures raw request string.
You can get it by C<< $res->captured_req_headers >> and C<< $res->captured_req_content >>.

=item proxy :Str

=item no_proxy :Str

=item headers :ArrayRef

=item cookie_jar :Object

(EXPERIMENTAL)

An instance of HTTP::CookieJar or equivalent class that supports the add and cookie_header methods

=back

=head2 Instance Methods

=head3 C<< $furl->request([$request,] %args) :Furl::Response >>

Sends an HTTP request to a specified URL and returns a instance of L<Furl::Response>.

I<%args> might be:

=over

=item scheme :Str = "http"

Protocol scheme. May be C<http> or C<https>.

=item host :Str

Server host to connect.

You must specify at least C<host> or C<url>.

=item port :Int = 80

Server port to connect. The default is 80 on C<< scheme => 'http' >>,
or 443 on C<< scheme => 'https' >>.

=item path_query :Str = "/"

Path and query to request.

=item url :Str

URL to request.

You can use C<url> instead of C<scheme>, C<host>, C<port> and C<path_query>.

=item headers :ArrayRef

HTTP request headers. e.g. C<< headers => [ 'Accept-Encoding' => 'gzip' ] >>.

=item content : Str | ArrayRef[Str] | HashRef[Str] | FileHandle

Content to request.

=back

If the number of arguments is an odd number, this method assumes that the
first argument is an instance of C<HTTP::Request>. Remaining arguments
can be any of the previously describe values (but currently there's no
way to really utilize them, so don't use it)

    my $req = HTTP::Request->new(...);
    my $res = $furl->request($req);

You can also specify an object other than HTTP::Request (e.g. Furl::Request),
but the object must implement the following methods:

=over 4

=item uri

=item method

=item content

=item headers

=back

These must return the same type of values as their counterparts in
C<HTTP::Request>.

You must encode all the queries or this method will die, saying
C<Wide character in ...>.

=head3 C<< $furl->get($url :Str, $headers :ArrayRef[Str] ) >>

This is an easy-to-use alias to C<request()>, sending the C<GET> method.

=head3 C<< $furl->head($url :Str, $headers :ArrayRef[Str] ) >>

This is an easy-to-use alias to C<request()>, sending the C<HEAD> method.

=head3 C<< $furl->post($url :Str, $headers :ArrayRef[Str], $content :Any) >>

This is an easy-to-use alias to C<request()>, sending the C<POST> method.

=head3 C<< $furl->put($url :Str, $headers :ArrayRef[Str], $content :Any) >>

This is an easy-to-use alias to C<request()>, sending the C<PUT> method.

=head3 C<< $furl->delete($url :Str, $headers :ArrayRef[Str] ) >>

This is an easy-to-use alias to C<request()>, sending the C<DELETE> method.

=head3 C<< $furl->env_proxy() >>

Loads proxy settings from C<< $ENV{HTTP_PROXY} >> and C<< $ENV{NO_PROXY} >>.

=head1 FAQ

=over 4

=item Does Furl depends on XS modules?

No. Although some optional features require XS modules, basic features are
available without XS modules.

Note that Furl requires HTTP::Parser::XS, which seems an XS module
but includes a pure Perl backend, HTTP::Parser::XS::PP.

=item I need more speed.

See L<Furl::HTTP>, which provides the low level interface of L<Furl>.
It is faster than C<Furl.pm> since L<Furl::HTTP> does not create response objects.

=item How do you use cookie_jar?

Furl does not directly support the cookie_jar option available in LWP. You can use L<HTTP::Cookies>, L<HTTP::Request>, L<HTTP::Response> like following.

    my $f = Furl->new();
    my $cookies = HTTP::Cookies->new();
    my $req = HTTP::Request->new(...);
    $cookies->add_cookie_header($req);
    my $res = $f->request($req)->as_http_response;
    $res->request($req);
    $cookies->extract_cookies($res);
    # and use $res.

=item How do you limit the response content length?

You can limit the content length by callback function.

    my $f = Furl->new();
    my $content = '';
    my $limit = 1_000_000;
    my %special_headers = ('content-length' => undef);
    my $res = $f->request(
        method          => 'GET',
        url             => $url,
        special_headers => \%special_headers,
        write_code      => sub {
            my ( $status, $msg, $headers, $buf ) = @_;
            if (($special_headers{'content-length'}||0) > $limit || length($content) > $limit) {
                die "over limit: $limit";
            }
            $content .= $buf;
        }
    );

=item How do you display the progress bar?

    my $bar = Term::ProgressBar->new({count => 1024, ETA => 'linear'});
    $bar->minor(0);
    $bar->max_update_rate(1);

    my $f = Furl->new();
    my $content = '';
    my %special_headers = ('content-length' => undef);;
    my $did_set_target = 0;
    my $received_size = 0;
    my $next_update  = 0;
    $f->request(
        method          => 'GET',
        url             => $url,
        special_headers => \%special_headers,
        write_code      => sub {
            my ( $status, $msg, $headers, $buf ) = @_;
            unless ($did_set_target) {
                if ( my $cl = $special_headers{'content-length'} ) {
                    $bar->target($cl);
                    $did_set_target++;
                }
                else {
                    $bar->target( $received_size + 2 * length($buf) );
                }
            }
            $received_size += length($buf);
            $content .= $buf;
            $next_update = $bar->update($received_size)
            if $received_size >= $next_update;
        }
    );

=item HTTPS requests claims warnings!

When you make https requests, IO::Socket::SSL may complain about it like:

    *******************************************************************
     Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
     is depreciated! Please set SSL_verify_mode to SSL_VERIFY_PEER
     together with SSL_ca_file|SSL_ca_path for verification.
     If you really don't want to verify the certificate and keep the
     connection open to Man-In-The-Middle attacks please set
     SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
    *******************************************************************

You should set C<SSL_verify_mode> explicitly with Furl's C<ssl_opts>.

    use IO::Socket::SSL;

    my $ua = Furl->new(
        ssl_opts => {
            SSL_verify_mode => SSL_VERIFY_PEER(),
        },
    );

See L<IO::Socket::SSL> for details.

=back

=head1 AUTHOR

Tokuhiro Matsuno E<lt>tokuhirom@gmail.comE<gt>

Fuji, Goro (gfx)

=head1 THANKS TO

Kazuho Oku

mala

mattn

lestrrat

walf443

lestrrat

audreyt

=head1 SEE ALSO

L<LWP>

L<IO::Socket::SSL>

L<Furl::HTTP>

L<Furl::Response>

=head1 LICENSE

Copyright (C) Tokuhiro Matsuno.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut