App-MBUtiny
view release on metacpan or search on metacpan
lib/App/MBUtiny/Storage/HTTP.pm view on Meta::CPAN
foreach my $storage ($self->http_storages) {
my $url = $storage->{url};
my $url_wop = $storage->{url_wop};
my $attr = $storage->{attr};
# Create object
my $client = new App::MBUtiny::Storage::HTTP::Client(
url => $url, # Base URL
timeout => $storage->{timeout}, # default: 180
($attr && isnt_void($attr)) ? (headers => $attr) : (),
);
unless ($client->status) {
$self->storage_status($sign, 0);
push @test, [0, $url_wop, sprintf("Can't connect to %s: %s", $url_wop, $client->error)];
next;
}
# Check server
unless ($client->check) {
$self->storage_status($sign, 0);
push @test, [0, $url_wop, sprintf("Server not running or not configured (%s): %s", $url_wop, $client->error)];
next;
}
push @test, [1, $url_wop];
}
$self->{test}->{$sign} = [@test];
return 1;
}
sub put {
my $self = shift;
my %params = @_; $self->maybe::next::method(%params);
return $self->storage_status(STORAGE_SIGN, -1) if $self->storage_status(STORAGE_SIGN) <= 0; # SKIP and set SKIP
my $status = 1;
my $name = $params{name}; # File name only
my $file = $params{file}; # Path to local file
my $src_size = $params{size} || 0;
foreach my $storage ($self->http_storages) {
my $url = $storage->{url};
my $url_wop = $storage->{url_wop};
my $comment = $storage->{comment} || "";
my $attr = $storage->{attr};
my $ostat = 1;
# Create object
my $client = new App::MBUtiny::Storage::HTTP::Client(
url => $url, # Base URL
timeout => $storage->{timeout}, # default: 180
($attr && isnt_void($attr)) ? (headers => $attr) : (),
no_check_redirect => 0,
);
unless ($client->status) {
$self->error(sprintf("Can't connect to %s: %s", $url_wop, $client->error));
$ostat = 0;
}
# Upload file
if ($ostat) {
$client->upload(file => $file, name => $name) or do {
$self->error(join("\n", $client->transaction, $client->error));
$ostat = 0;
};
}
# Get file size
if ($ostat) {
my %info = $client->fileinfo(name => $name);
unless ($client->status) {
$self->error(join("\n", $client->transaction, $client->error));
$ostat = 0;
}
my $dst_size = $info{size} || 0;
unless ($src_size == $dst_size) {
$self->error(sprintf("An error occurred while sending data to %s. Sizes are different: SRC=%d; DST=%d", $url_wop, $src_size, $dst_size));
$ostat = 0;
}
}
# Fixup!
$self->fixup("put", $ostat, $comment) if $storage->{fixup};
$status = 0 unless $ostat;
}
$self->storage_status(STORAGE_SIGN, 0) unless $status;
}
sub get {
my $self = shift;
my %params = @_;
if ($self->storage_status(STORAGE_SIGN) <= 0) { # SKIP and set SKIP
$self->maybe::next::method(%params);
return $self->storage_status(STORAGE_SIGN, -1);
}
my $name = $params{name}; # archive name
my $file = $params{file}; # destination archive file path
foreach my $storage ($self->http_storages) {
my $url = $storage->{url};
my $url_wop = $storage->{url_wop};
my $attr = $storage->{attr};
# Create object
my $client = new App::MBUtiny::Storage::HTTP::Client(
url => $url, # Base URL
timeout => $storage->{timeout}, # default: 180
($attr && isnt_void($attr)) ? (headers => $attr) : (),
no_check_redirect => 0,
);
unless ($client->status) {
$self->error(sprintf("Can't connect to %s: %s", $url_wop, $client->error));
next;
}
# Download file
$client->download(file => $file, name => $name) or do {
$self->error(join("\n", $client->transaction, $client->error));
next;
};
my $src_size = 0;
if (my $res = $client->res) {
lib/App/MBUtiny/Storage/HTTP.pm view on Meta::CPAN
);
unless ($client->status) {
$self->error(sprintf("Can't connect to %s: %s", $url_wop, $client->error));
$ostat = 0;
}
# Get list
if ($ostat) {
my @ls = $client->filelist(host => $self->{name});
if ($client->status) {
push @list, grep { defined($_) && length($_) } @ls;
} else {
$self->error(join("\n", $client->transaction, $client->error));
$ostat = 0;
}
}
}
$self->{list}->{$sign} = [uniq(@list)];
return 1;
}
1;
package App::MBUtiny::Storage::HTTP::Client;
use vars qw/ $VERSION /;
$VERSION = '1.00';
use Fcntl qw/ :flock /;
use File::Basename;
use CTK::ConfGenUtil;
use CTK::Util qw/ trim /;
use base qw/ WWW::MLite::Client /;
use constant {
CONTENT_TYPE => "application/octet-stream",
};
sub new {
my $class = shift;
my %params = @_;
$params{ua_opts} ||= { agent => "MBUtiny/$VERSION" };
$params{content_type} ||= CONTENT_TYPE;
$params{no_check_redirect} //= 1;
return $class->SUPER::new(%params);
}
sub check {
my $self = shift;
$self->request("HEAD");
return $self->status;
}
sub filelist {
my $self = shift;
my %args = @_;
my $string_ret = $self->request(GET => $self->_merge_path_query($args{path}, $args{host})) || "";
my @array_ret = map {$_ = trim($_)} split /\s*\n+\s*/, $string_ret;
return wantarray ? @array_ret : $string_ret;
}
sub upload {
my $self = shift;
my %args = @_;
my $file = $args{file} || ''; # File for uploading! /path/to/file.tar.gz
my $name = $args{name} || basename($file); # File name! file.tar.gz
my $path = $args{path} ? sprintf("%s/%s", $args{path}, $name) : $name; # Path for request: /foo/bar
$self->request(PUT => $self->_merge_path_query($path), sub {
my $req = shift; # HTTP::Request object
$req->header('Content-Type', CONTENT_TYPE);
if (-e $file and -f $file) {
my $size = (-s $file) || 0;
return 0 unless $size;
#my $sizef = $size;
my $fh;
$req->content(sub {
unless ($fh) {
open($fh, "<", $file) or do {
$self->error(sprintf("Can't open file %s to read: %s", $file, $!));
return "";
};
binmode($fh);
}
my $buf = "";
if (my $n = read($fh, $buf, 1024)) {
#$sizef -= $n;
#printf STDERR ">>> sizef=%d; n=%d\n", $sizef, $n;
return $buf;
}
close($fh);
return "";
});
return $size;
}
return 0;
});
return $self->status;
}
sub fileinfo {
my $self = shift;
my %args = @_;
my $name = $args{name}; # File name! file.tar.gz
unless ($name) {
$self->error("The file name (name attribute) not specified!");
return ();
}
my $path = $args{path} ? sprintf("%s/%s", $args{path}, $name) : $name; # Path for request: /foo/bar
$self->request(HEAD => $self->_merge_path_query($path));
return () unless $self->status;
my %ret = ();
my $res = $self->res;
if ($res) {
$ret{code} = $res->code || 0;
$ret{message} = $res->message || '';
$ret{size} = $res->content_length || 0;
$ret{content_type} = $res->content_type || '';
}
return %ret;
}
sub download {
my $self = shift;
my %args = @_;
my $file = $args{file} || ''; # File for downloading! /path/to/file.tar.gz
my $name = $args{name} || basename($file); # File name! file.tar.gz
my $path = $args{path} ? sprintf("%s/%s", $args{path}, $name) : $name; # Path for request: /foo/bar
( run in 2.568 seconds using v1.01-cache-2.11-cpan-b16cb0d3907 )