File-Download
view release on metacpan or search on metacpan
lib/File/Download.pm view on Meta::CPAN
package File::Download;
# use 'our' on v5.6.0
use vars qw($VERSION @EXPORT_OK %EXPORT_TAGS $DEBUG);
$DEBUG = 0;
$VERSION = '0.3';
use base qw(Class::Accessor);
File::Download->mk_accessors(qw(mode overwrite outfile flength size status user_agent));
# We are exporting functions
use base qw/Exporter/;
# Export list - to allow fine tuning of export table
@EXPORT_OK = qw( download );
use strict;
use LWP::UserAgent ();
use LWP::MediaTypes qw(guess_media_type media_suffix);
use URI ();
use HTTP::Date ();
sub DESTROY { }
$SIG{INT} = sub { die "Interrupted\n"; };
$| = 1; # autoflush
sub download {
my $self = shift;
my ($url) = @_;
my $file;
$self->{user_agent} = LWP::UserAgent->new(
agent => "File::Download/$VERSION ",
keep_alive => 1,
env_proxy => 1,
) if !$self->{user_agent};
my $ua = $self->{user_agent};
my $res = $ua->request(HTTP::Request->new(GET => $url),
sub {
$self->{status} = "Beginning download\n";
unless(defined $file) {
my ($chunk,$res,$protocol) = @_;
my $directory;
if (defined $self->{outfile} && -d $self->{outfile}) {
($directory, $self->{outfile}) = ($self->{outfile}, undef);
}
unless (defined $self->{outfile}) {
# find a suitable name to use
$file = $res->filename;
# if this fails we try to make something from the URL
unless ($file) {
my $req = $res->request; # not always there
my $rurl = $req ? $req->url : $url;
$file = ($rurl->path_segments)[-1];
if (!defined($file) || !length($file)) {
$file = "index";
my $suffix = media_suffix($res->content_type);
$file .= ".$suffix" if $suffix;
}
elsif ($rurl->scheme eq 'ftp' ||
$file =~ /\.t[bg]z$/ ||
$file =~ /\.tar(\.(Z|gz|bz2?))?$/
) {
# leave the filename as it was
}
else {
my $ct = guess_media_type($file);
unless ($ct eq $res->content_type) {
# need a better suffix for this type
my $suffix = media_suffix($res->content_type);
$file .= ".$suffix" if $suffix;
}
}
}
# validate that we don't have a harmful filename now. The server
# might try to trick us into doing something bad.
if ($file && !length($file) ||
$file =~ s/([^a-zA-Z0-9_\.\-\+\~])/sprintf "\\x%02x", ord($1)/ge)
{
die "Will not save <$url> as \"$file\".\nPlease override file name on the command line.\n";
}
if (defined $directory) {
require File::Spec;
$file = File::Spec->catfile($directory, $file);
}
# Check if the file is already present
if (-l $file) {
die "Will not save <$url> to link \"$file\".\nPlease override file name on the command line.\n";
( run in 1.058 second using v1.01-cache-2.11-cpan-483215c6ad5 )