我在Azure Blob服务错误代码列表https://msdn.microsoft.com/en-us/library/dd179439.aspx中看不到与错误596相关的任何信息。
我正在尝试将一些块上传到Azure服务,并从API获取代码596和描述'Broken pipe'的回复。
有没有人遇到过这个?
(N.B。是的,我知道下面的代码尚未完成,因为代码原样没有上传最终的块)
#!/usr/bin/perl
use 5.014;
use strict;
use warnings;
use autodie;
use Data::Dumper;
use Digest::MD5 qw(md5_base64);
use Crypt::PRNG::Fortuna qw(random_bytes_b64u random_bytes);
use Digest::SHA qw(hmac_sha256_base64);
use Getopt::Long;
use Sys::Syslog qw( :DEFAULT setlogsock);
use File::stat;
use AnyEvent;
use AnyEvent::HTTP;
use Time::Piece;
use Encode qw(decode encode);
use MIME::Base64 qw(encode_base64 decode_base64 encode_base64url);
use FileHandle;
use Fcntl ':flock', 'SEEK_SET';
delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
use sigtrap 'handler' => \&term_handler, 'normal-signals';
####### PARAMS
my $script="upload.pl";
my $maxSingleUpload=1048576; # Maximum size of a single attempt upload (in bytes);
my $multiChunkSize=4194304; # Maximum size of a single block (in bytes)
my $multiLimit=6; # Maximum number of parallel HTTP requests
####### AZURE
my $azureKey="<REMOVED>";
my $azureKeyBin=decode_base64($azureKey);
####### ARGS
my ($vault,$container,$localfile,$remotefile);
my $debug=0;
GetOptions(
"vault|v=s" => \$vault,
"container|c=s" => \$container,
"localfile|l=s" => \$localfile,
"remotefile|r=s" => \$remotefile,
"debug|d+" => \$debug
);
if (!defined $vault || !defined $container || !defined $localfile || !defined $remotefile) {
say "USAGE: -v <vault> -c <container> -l <localfile> -r <remotefile> [-d (debug)]";
exit 1;
}
if (!-e $localfile) {
say "Local file does not exist !";
exit 1;
}
####### Vars
my ($wholeChunks,$chunkRemainder,$runID,$condvar,@offsets,@blocklist);
my $activeCount=0;
my $putBlockURL="https://${vault}.blob.core.windows.net/${container}/${remotefile}?comp=block&blockid=";
####### FUNCTIONS
# Quotient remainder calculator
sub qrem {
use integer;
my( $dividend, $divisor ) = @_;
my $quotient = $dividend / $divisor;
my $remainder = $dividend % $divisor;
my @result = ( $quotient, $remainder );
return @result;
}
# Do pad
sub doPad {
my ($raw) = @_;
while (length($raw) % 4) {
$raw .= '=';
}
return $raw;
}
# Random
sub getRandom {
my ($len) = @_;
#return doPad(random_bytes_b64u($len));
return doPad(encode_base64(random_bytes($len)));
}
# Term handler
sub term_handler {
doLog("err","term_handler: Program terminated early due to user input");
exit 2;
}
# Log sub
sub doLog {
my ($priority,$msg) = @_;
return 0 unless ($priority =~ /info|err|debug/);
setlogsock('unix');
openlog($script, 'pid,cons', 'user');
syslog($priority, $msg);
closelog();
return 1;
}
# Get file size
sub fileSz {
my($file) = @_;
my $stat = stat($file);
return $stat->size;
}
# Get data
sub readData {
my ($file,$length,$offset)=@_;
my $fh = FileHandle->new;
my ($data);
if ($debug) { say "Reading ${file} offset ${offset} for length ${length}";}
#open ($fh,"<",$file);
$fh->open("< $file");
binmode($fh);
seek($fh,$offset,SEEK_SET);
read($fh,$data,$length);
if ($debug) { say "readData read ".byteSize($data);}
#close($fh);
$fh->close;
return $data;
}
# Calc MD5
sub calcMD5 {
my ($data)=@_;
my $hash = md5_base64($data);
return doPad($hash);
}
# Populate offsets
sub populateOffsets {
my ($count,$offsetSize)=@_;
if (!defined $count || !defined $offsetSize) {exit 1;}
my $offset=0;
my @offsets;
for my $i (1..$count) {
push @offsets,$offset;
$offset = $offset + $offsetSize;
}
return @offsets;
}
# Calc auth string
sub azureAuth {
my($t,$signstring)=@_;
if (!defined $signstring) { exit 1;}
if ($debug) {say "String to sign:${signstring}";}
my $auth;
$auth=doPad(hmac_sha256_base64($signstring,$azureKeyBin));
if ($debug) { say "Sig:${auth}";}
return $auth;
}
# Byte size
sub byteSize {
use bytes;
my ($inval)=@_;
return length($inval);
}
# Process
sub doProcess {
return if $activeCount >= $multiLimit;
my $offset = shift @offsets;
return if !defined $offset;
$activeCount++;
if ($debug) { say "Active:${activeCount}, Offset:${offset}";}
$condvar->begin;
my $t = localtime;
my $tNow = $t->strftime();
my $blockid = getRandom(8);
my $subRunID=getRandom(5);
my $contentLength=$multiChunkSize-1;
my $content = readData($localfile,$contentLength,$offset);
my $hash = calcMD5($content);
if ($debug) { say "Block ID:${blockid}, Hash: ${hash}";}
my $url = $putBlockURL.$blockid;
my $canocResource="/${vault}/${container}/${remotefile}\nblockid:${blockid}\ncomp:block";
my $hdrs="x-ms-client-request-id:${runID}\nx-ms-date:${tNow}\nx-ms-version:2009-09-19";
my $byteLength=byteSize(${content});
my $canocHeaders=encode('UTF-8',"PUT\n\n\n${byteLength}\n${hash}\n\n\n\n\n\n\n\n${hdrs}\n${canocResource}",Encode::FB_CROAK);
my $authData=azureAuth($t,$canocHeaders);
if ($debug) {say "Length:${byteLength}";say "Sig: ${authData}"; say "URL:${url}";}
my $azureArr = {
"Authorization"=>"SharedKey ${vault}:${authData}",
"Content-Length"=>${byteLength},
"Content-MD5"=>${hash},
"x-ms-version"=>"2009-09-19",
"x-ms-date"=>${tNow},
"x-ms-client-request-id"=>"${runID}"
};
####### ERROR OCCURS HERE ....
http_request "PUT" => $url,
persistent=>0,
headers=>$azureArr,
body=>$content,
sub {
my ($body, $hdr) = @_;
say Dumper($hdr);
#say "received, Size: ", length $body;
#say $body;
$activeCount--;
$condvar->end;
doProcess();
};
return 1;
}
####### MAIN
$runID=getRandom(5);
doLog("info","${runID} Starting upload for ${localfile} (${remotefile})");
if (fileSz($localfile)<$maxSingleUpload) {
if ($debug) {say "Using single upload method";}
} else {
if ($debug) {say "Using multi-upload method";}
# Calculate chunk quantity
my @chunks = qrem(fileSz($localfile),$multiChunkSize);
$wholeChunks=$chunks[0];
$chunkRemainder=$chunks[1];
if ($debug) {say "Whole chunks (${multiChunkSize}):${wholeChunks}, Remainder:${chunkRemainder}";}
# Init
@offsets=populateOffsets(${wholeChunks},${multiChunkSize});
say Dumper(@offsets);
$condvar = AnyEvent->condvar;
# DO IT
for (1..$multiLimit) {
doProcess();
}
$condvar->recv;
}
doLog("info","${runID} Upload complete");
exit 0;
答案 0 :(得分:3)
错误596是AnyEvent :: HTTP返回的客户端错误。您需要在本地调查以了解您遇到此错误的原因。
有关详细信息,请参阅此页面: https://metacpan.org/pod/AnyEvent::HTTP
596 - TLS协商,请求发送和报头处理期间的错误。