File Coverage

lib/Rex/Commands/Download.pm
Criterion Covered Total %
statement 41 89 46.0
branch 2 28 7.1
condition 1 9 11.1
subroutine 12 16 75.0
pod 1 1 100.0
total 57 143 39.8


line stmt bran cond sub pod time code
1             #
2             # (c) Jan Gehring
3             #
4              
5             =head1 NAME
6              
7             Rex::Commands::Download - Download remote files
8              
9             =head1 DESCRIPTION
10              
11             With this module you can download a remotefile via sftp, http and ftp from a host to your local computer.
12              
13             Version <= 1.0: All these functions will not be reported.
14              
15             =head1 SYNOPSIS
16              
17             # sftp
18             task "download", "remoteserver", sub {
19             download "/remote/file", "localfile";
20             };
21              
22             # http
23             task "download2", sub {
24             download "http://server/remote/file";
25             };
26              
27              
28             =head1 EXPORTED FUNCTIONS
29              
30             =cut
31              
32             package Rex::Commands::Download;
33              
34 32     32   464 use v5.12.5;
  32         132  
35 32     32   210 use warnings;
  32         124  
  32         869  
36 32     32   337 use Rex::Helper::UserAgent;
  32         110  
  32         571  
37 32     32   1227 use Carp;
  32         77  
  32         2447  
38              
39             our $VERSION = '1.14.3'; # VERSION
40              
41 32     32   215 use vars qw($has_wget $has_curl $has_lwp);
  32         92  
  32         5156  
42              
43             # check which download type we should use
44             BEGIN {
45              
46 32 50   32   285 if ( $^O !~ m/^MSWin/ ) {
47 32         193109 system("which wget >/dev/null 2>&1");
48 32         1505 $has_wget = !$?;
49              
50 32         162715 system("which curl >/dev/null 2>&1");
51 32         1851 $has_curl = !$?;
52             }
53              
54 32         663 eval {
55 32         2327 require Rex::Helper::UserAgent;
56 32         463 $has_lwp = 1;
57             };
58              
59 32 50 33     9149 if ( $^O =~ m/^MSWin/ && !$has_lwp ) {
60 0         0 Rex::Logger::info("Please install LWP::UserAgent to allow file downloads.");
61             }
62              
63             }
64              
65             require Rex::Exporter;
66              
67 32     32   534 use vars qw(@EXPORT);
  32         292  
  32         4808  
68 32     32   475 use base qw(Rex::Exporter);
  32         346  
  32         7586  
69              
70 32     32   464 use Rex::Commands::Fs;
  32         187  
  32         1293  
71 32     32   454 use Rex::Helper::Path;
  32         238  
  32         7059  
72 32     32   460 use Rex::Interface::Fs;
  32         271  
  32         1080  
73 32     32   1552 use File::Basename qw(basename);
  32         178  
  32         30868  
74              
75             @EXPORT = qw(download);
76              
77             =head2 download($remote, [$local])
78              
79             Perform a download. If no local file is specified it will download the file to the current directory.
80              
81             task "download", "remoteserver", sub {
82             download "/remote/file", "localfile";
83             };
84              
85             task "download", sub {
86             download "http://www.rexify.org/index.html", "localfile.html";
87             };
88              
89             =cut
90              
91             sub download {
92 0     0 1   my ( $remote, $local, %option ) = @_;
93              
94 0 0         unless ($local) {
95 0           $local = basename($remote);
96             }
97              
98 0 0         if ( -d $local ) {
99 0           $local = $local . '/' . basename($remote);
100             }
101              
102 0           Rex::Logger::debug("saving file to $local");
103 0           $remote = resolv_path($remote);
104 0           $local = resolv_path( $local, 1 );
105              
106 0 0         if ( $remote =~ m/^(https?|ftp):\/\// ) {
107 0           _http_download( $remote, $local, %option );
108             }
109             else {
110 0           _sftp_download( $remote, $local, %option );
111             }
112             }
113              
114             sub _sftp_download {
115 0     0     my $remote = shift;
116 0           my $local = shift;
117              
118 0           my $fs = Rex::Interface::Fs->create;
119              
120 0           Rex::Logger::debug("Downloading via SFTP");
121              
122 0 0         unless ( is_file($remote) ) {
123 0           Rex::Logger::info("File $remote not found");
124 0           die("$remote not found.");
125             }
126              
127 0 0         unless ( is_readable($remote) ) {
128 0           Rex::Logger::info("File $remote is not readable.");
129 0           die("$remote is not readable.");
130             }
131              
132 0           $fs->download( $remote, $local );
133              
134             }
135              
136             sub _http_download {
137 0     0     my ( $remote, $local, %option ) = @_;
138              
139 0           my $content = _get_http( $remote, %option );
140              
141 0 0         open( my $fh, ">", $local ) or die($!);
142 0           binmode $fh;
143 0           print $fh $content;
144 0           close($fh);
145             }
146              
147             sub _get_http {
148 0     0     my ( $url, %option ) = @_;
149              
150 0           my $html;
151 0 0         if ($has_curl) {
    0          
    0          
152 0           Rex::Logger::debug("Downloading via curl");
153 0 0 0       if ( exists $option{user} && exists $option{password} ) {
154 0           $html =
155             qx{curl -u '$option{user}:$option{password}' -# -L -k '$url' 2>/dev/null};
156             }
157             else {
158 0           $html = qx{curl -# -L -k '$url' 2>/dev/null};
159             }
160             }
161             elsif ($has_wget) {
162 0           Rex::Logger::debug("Downloading via wget");
163 0 0 0       if ( exists $option{user} && exists $option{password} ) {
164 0           $html =
165             qx{wget --http-user=$option{user} '--http-password=$option{password}' --no-check-certificate -O - '$url' 2>/dev/null};
166             }
167             else {
168 0           $html = qx{wget --no-check-certificate -O - '$url' 2>/dev/null};
169             }
170             }
171             elsif ($has_lwp) {
172 0           Rex::Logger::debug("Downloading via LWP::UserAgent");
173 0           my $ua = Rex::Helper::UserAgent->new;
174 0           my $resp = $ua->get( $url, %option );
175 0 0         if ( $resp->is_success ) {
176 0           $html = $resp->content;
177             }
178             else {
179 0           confess "Error downloading $url.";
180             }
181             }
182             else {
183 0           die("No tool found to download something. (curl, wget, LWP::Simple)");
184             }
185              
186 0           return $html;
187             }
188              
189             1;