Skip to content

Instantly share code, notes, and snippets.

@Avis20
Last active November 19, 2020 17:26
Show Gist options
  • Save Avis20/85921fe70a3c43e0310b60fffa63d599 to your computer and use it in GitHub Desktop.
Save Avis20/85921fe70a3c43e0310b60fffa63d599 to your computer and use it in GitHub Desktop.
for test
#!/usr/bin/env perl
=head
Send curl multipart/form-data aws s3
* Creating a POST Policy - https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html
* POST Upload Example - https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
=cut
use strict;
use warnings;
use JSON::XS qw(decode_json encode_json);
use Digest::SHA qw(hmac_sha256 hmac_sha256_hex);
use WWW::Curl::Easy;
use WWW::Curl::Form;
use MIME::Base64;
use DateTime;
my $access_key = 'YOUR_ACCESS_KEY_ID';
my $secret_key = 'YOUR_SECRET_KEY';
my $bucket = 'YOUR_BUCKET_NAME';
my $region = 'us-east-1'; # us-west-2, us-east-1, etc
my $acl = 'public-read'; # private, public-read, etc
my $s3_request = 's3/aws4_request';
my $url = sprintf('https://%s.s3.%s.%s', $bucket, $region, 'amazonaws.com');
warn "Upload to [$url]";
# file info
my $file_path = $ARGV[0] or die 'file is required!';
my $file_type = 'image/jpeg';
my ( $file_name, $extension ) = $file_path =~ m/.*\/(.*)\.(.*)$/;
$file_name .= '.'.$extension;
my $dt = DateTime->now();
my $long_date = sprintf('%sT%sZ', $dt->ymd(''), $dt->hms(''));
my $short_date = $dt->ymd('');
my $credential = sprintf('%s/%s/%s/%s', $access_key, $short_date, $region, $s3_request);
# policy
$dt->add(days => 1); # policy expired after 24 hours
my $expiration = sprintf('%sT%sZ', $dt->ymd('-'), $dt->hms(':'));
my $policy = encode_base64(encode_json({
'expiration' => $expiration,
'conditions' => [
{ 'acl' => $acl },
{ 'bucket' => $bucket },
[ 'starts-with', '$Content-Type', '' ],
[ 'starts-with', '$key', '' ],
{ 'x-amz-algorithm' => 'AWS4-HMAC-SHA256' },
{ 'x-amz-credential' => $credential },
{ 'x-amz-date' => $long_date }
],
}));
# signature
my $string_to_sign = hmac_sha256($short_date, 'AWS4' . $secret_key);
$string_to_sign = hmac_sha256($region, $string_to_sign);
$string_to_sign = hmac_sha256('s3', $string_to_sign);
$string_to_sign = hmac_sha256('aws4_request', $string_to_sign);
my $signature = hmac_sha256_hex($policy, $string_to_sign);
my $curl = WWW::Curl::Easy->new;
my $curlf = WWW::Curl::Form->new;
$curlf->formadd( 'Content-Type', $file_type );
$curlf->formadd( 'acl', $acl );
$curlf->formadd( 'key', $file_name );
$curlf->formadd( 'policy', $policy );
$curlf->formadd( 'x-amz-algorithm', 'AWS4-HMAC-SHA256' );
$curlf->formadd( 'x-amz-credential', $credential );
$curlf->formadd( 'x-amz-date', $long_date );
$curlf->formadd( 'x-amz-signature', $signature );
$curlf->formaddfile($file_path, 'file', $file_type);
$curl->setopt( CURLOPT_HTTPPOST, $curlf );
$curl->setopt( CURLOPT_HEADER, 1 );
# $curl->setopt( CURLOPT_POST, 1 ); # why not work with?
$curl->setopt( CURLOPT_URL, $url);
my $response;
$curl->setopt( CURLOPT_WRITEDATA, \$response );
my $retcode = $curl->perform;
warn "response=[$response]";
exit;
@Avis20
Copy link
Author

Avis20 commented Nov 19, 2020

Пример запуска

$ perl Perl_Amazon_S3_File_Upload.pl /home/avis/projects/script/upload_s3/file/cat.jpg
Upload to [https://sigv4examplebucket.s3.us-east-1.amazonaws.com] at Perl_Amazon_S3_File_Upload.pl line 25.
response=[HTTP/1.1 100 Continue

HTTP/1.1 204 No Content
Accept-Ranges: bytes
Content-Security-Policy: block-all-mixed-content
ETag: "c803f4307fc25f7900436faa5bd666af"
Location: https://sigv4examplebucket.s3.us-east-1.amazonaws.com/sigv4examplebucket/cat.jpg
Vary: Origin
X-Amz-Request-Id: 1644568F844DE9213
X-Xss-Protection: 1; mode=block
Date: Thu, 19 Nov 2020 17:17:22 GMT

] at Perl_Amazon_S3_File_Upload.pl line 84.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment