view release on metacpan or search on metacpan
t/04_handler_not_found.t
t/10_lambda_next.t
t/11_lambda_response.t
t/12_lambda_error.t
t/13_lambda_init_error.t
t/14_streaming.t
t/15_lambda_response_streaming.t
t/20_psgi.t
t/21_psgi_response_streaming.t
t/lib/BootstrapMock.pm
t/test_handlers/echo.pl
t/test_handlers/error.pl
t/test_handlers/init_error.pl
t/test_handlers/streaming.pl
t/testdata/alb-base64-request.json
t/testdata/alb-get-request.json
t/testdata/alb-post-request.json
t/testdata/apigateway-base64-request.json
t/testdata/apigateway-get-request.json
t/testdata/apigateway-post-request.json
t/testdata/apigateway-v2-base64-request.json
t/testdata/apigateway-v2-get-request.json
t/testdata/apigateway-v2-post-request.json
t/testdata/function-urls-get-request.json
t/testdata/function-urls-post-base64-request.json
t/testdata/function-urls-post-request.json
xt/21_mojo.t
xt/21_mojo_custom_domain.t
xt/21_mojoapp.pl
xt/22_dancer.t
xt/22_dancerapp.pl
META.yml
MANIFEST
"JSON::Types" : "0.05",
"JSON::XS" : "4.0",
"MIME::Base64" : "0",
"Plack" : "1.0047",
"Plack::Middleware::ReverseProxy" : "0.16",
"Try::Tiny" : "0.30",
"URI::Escape" : "0",
"perl" : "5.026000"
}
},
"test" : {
"requires" : {
"File::Slurp" : "9999.25",
"Starman" : "0",
"Test::Deep" : "1.128",
"Test::More" : "0.98",
"Test::SharedFork" : "0",
"Test::TCP" : "2.19",
"Test::Warn" : "0"
}
}
Finally, create new function using awscli.
$ aws --region "$REGION" --profile "$PROFILE" lambda create-function \
--function-name "hello-perl" \
--zip-file "fileb://handler.zip" \
--handler "handler.handle" \
--runtime provided.al2023 \
--role arn:aws:iam::xxxxxxxxxxxx:role/service-role/lambda-custom-runtime-perl-role \
--layers "arn:aws:lambda:$REGION:445285296882:layer:perl-5-38-runtime-al2023-x86_64:1"
It also supports [response streaming](https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html).
sub handle {
my ($payload, $context) = @_;
return sub {
my $responder = shift;
my $writer = $responder->('application/json');
$writer->write('{"foo": "bar"}');
$writer->close;
};
}
# FROM public.ecr.aws/shogo82148/p5-aws-lambda:base-5.38.al2023
COPY handler.pl /var/task/
CMD [ "handler.handle" ]
Build the hello-perl container image locally:
$ docker build -t hello-perl .
To check if this is working, start the container image locally using the Lambda Runtime Interface Emulator:
$ docker run -p 9000:8080 hello-perl:latest
Now, you can test a function invocation with cURL.
$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
To upload the container image, you need to create a new ECR repository in your account and tag the local image to push it to ECR.
$ aws ecr create-repository --repository-name hello-perl --image-scanning-configuration scanOnPush=true
$ docker tag hello-perl:latest 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
$ aws ecr get-login-password | docker login --username AWS --password-stdin 123412341234.dkr.ecr.sa-east-1.amazonaws.com
$ docker push 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
Finally, create new function using awscli.
$ aws --region "$REGION" --profile "$PROFILE" lambda create-function \
--function-name "hello-perl" \
--code ImageUri=123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest \
--handler "handler.handle" \
--runtime provided.al2023 \
--role arn:aws:iam::xxxxxxxxxxxx:role/service-role/lambda-custom-runtime-perl-role
## Run in Local using Docker
Prebuilt Docker Images based on [https://hub.docker.com/r/lambci/lambda/](https://hub.docker.com/r/lambci/lambda/) are available.
You can pull from [https://gallery.ecr.aws/shogo82148/p5-aws-lambda](https://gallery.ecr.aws/shogo82148/p5-aws-lambda) or [https://hub.docker.com/r/shogo82148/p5-aws-lambda](https://hub.docker.com/r/shogo82148/p5-aws-lambda),
and build zip archives to deploy.
# Install the dependency.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:build-5.38.al2023 \
cpanm --notest --local-lib extlocal --no-man-pages --installdeps .
# run an event.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:5.38.al2023 \
handler.handle '{"some":"event"}'
## Pre-installed modules
The following modules are pre-installed for convenience.
- [AWS::Lambda](https://metacpan.org/pod/AWS%3A%3ALambda)
# FROM public.ecr.aws/shogo82148/p5-aws-lambda:base-5.38-paws.al2023
COPY handler.pl /var/task/
CMD [ "handler.handle" ]
## Run in Local using Docker for Paws
use the `build-$VERSION-paws.al2023` and `$VERSION-paws.al2023` tag on [https://gallery.ecr.aws/shogo82148/p5-aws-lambda](https://gallery.ecr.aws/shogo82148/p5-aws-lambda) or [https://hub.docker.com/r/shogo82148/p5-aws-lambda](https://hub.docker.com/...
# Install the dependency.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:build-5.38-paws.al2023 \
cpanm --notest --local-lib extlocal --no-man-pages --installdeps .
# run an event.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:5.38-paws.al2023 \
handler.handle '{"some":"event"}'
# CREATE MODULE LAYER
To create custom module layer such as the Paws Layer,
install the modules into `/opt/lib/perl5/site_perl` in the layer.
# Create Some::Module Layer
docker run --rm \
-v $(PWD):/var/task \
-v $(PATH_TO_LAYER_DIR)/lib/perl5/site_perl:/opt/lib/perl5/site_perl \
shogo82148/p5-aws-lambda:build-5.38.al2023 \
cpanm --notest --no-man-pages Some::Module
cd $(PATH_TO_LAYER_DIR) && zip -9 -r $(PATH_TO_DIST)/some-module.zip .
# MAINTENANCE AND SUPPORT
Supported Perl versions are the same as those officially supported by the Perl community ([perlpolicy](https://metacpan.org/pod/perlpolicy)).
It means that we support the two most recent stable release series.
# LEGACY CUSTOM RUNTIME ON AMAZON LINUX
We also provide the layers for legacy custom runtime as known as "provided".
author/build-paws-al2.sh view on Meta::CPAN
"x86_64")
ARCH=x86_64;;
"aarch64")
ARCH=arm64;;
*)
echo "unknown architecture: $(uname -m)"
esac
cd /opt
unzip "/var/task/.perl-layer/dist/perl-$TAG-runtime-al2-$ARCH.zip"
/opt/bin/cpanm --notest --no-man-pages "Paws@$PAWS_VERSION"
# remove pods
find /opt/lib/perl5/site_perl -type f -a -name '*.pod' -delete
author/build-paws-al2023.sh view on Meta::CPAN
"x86_64")
ARCH=x86_64;;
"aarch64")
ARCH=arm64;;
*)
echo "unknown architecture: $(uname -m)"
esac
cd /opt
unzip "/var/task/.perl-layer/dist/perl-$TAG-runtime-al2023-$ARCH.zip"
/opt/bin/cpanm --notest --no-man-pages "Paws@$PAWS_VERSION"
# remove pods
find /opt/lib/perl5/site_perl -type f -a -name '*.pod' -delete
author/build-perl-al2.sh view on Meta::CPAN
IO_SOCKET_SSL_VERSION=2.091
MOZILLA_CA_VERSION=20250602
LOCAL_LIB_VERSION=2.000029
# workaround for https://github.com/aws/aws-lambda-base-images/issues/245
# https://github.com/aws/aws-lambda-base-images/issues/245#issuecomment-2717501840
cat > /etc/yum.repos.d/amzn2-extras.repo << 'EOREPO'
[amzn2extra-openssl-snapsafe]
name=Amazon Extras repo for openssl-snapsafe
enabled=1
mirrorlist=$awsproto://$amazonlinux.$awsregion.$awsdomain/2/extras/openssl-snapsafe/latest/$basearch/mirror.list
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2
priority=10
skip_if_unavailable=1
report_instanceid=yes
EOREPO
yum upgrade -y openssl-snapsafe-libs
# build-provided.al2 lacks some development packages
yum install -y openssl openssl-devel
author/build-perl-al2.sh view on Meta::CPAN
export PERL_MB_OPT="--installdirs=vendor --ccflags=-I/opt/include --lddlflags=-L/opt/lib --config installman1dir= --config installsiteman1dir= --config installman3dir= --config installsiteman3dir="
export PERL_MM_USE_DEFAULT=1
# install pre-installed modules
curl -fsSL --compressed http://cpanmin.us | perl -i -pe 's(^#!.*perl$)(#!/opt/bin/perl)' > /tmp/cpanm
install /tmp/cpanm /opt/bin/cpanm
curl -fsSL --compressed https://raw.githubusercontent.com/skaji/cpm/main/cpm | perl -i -pe 's(^#!.*perl$)(#!/opt/bin/perl)' > /tmp/cpm
install /tmp/cpm /opt/bin/cpm
# Net::SSLeay needs special CCFLAGS and LIBS to link
PERL_MM_OPT="INSTALLDIRS=vendor INSTALLMAN1DIR=none INSTALLMAN3DIR=none" /opt/bin/cpanm --notest "Net::SSLeay@$NET_SSLEAY_VERSION"
/opt/bin/cpanm --notest \
"Carton@$CARTON_VERSION" \
"AWS::XRay@$AWS_XRAY_VERSION" \
"JSON@$JSON_VERSION" \
"Cpanel::JSON::XS@$CPANEL_JSON_XS_VERSION" \
"JSON::XS@$JSON_XS_VERSION" \
"JSON::MaybeXS@$JSON_MAYBEXS_VERSION" \
"YAML@$YAML_VERSION" \
"YAML::Tiny@$YAML_TINY_VERSION" \
"YAML::XS@$YAML_XS_VERSION" \
"IO::Socket::SSL@$IO_SOCKET_SSL_VERSION" \
"Mozilla::CA@$MOZILLA_CA_VERSION" \
"local::lib@$LOCAL_LIB_VERSION"
/opt/bin/cpanm --notest .
# replace shebang to the absolute path of perl
cp script/bootstrap /opt/
perl -i -pe 's(^#!perl$)(#!/opt/bin/perl)' /opt/bootstrap
# remove POD(Plain Old Documentation)
yum install -y perl-ExtUtils-MakeMaker
cd author/pod-stripper
perl /opt/bin/cpanm --installdeps --notest .
perl ./scripts/pod_stripper.pl /opt/lib/perl5
author/build-perl-al2023.sh view on Meta::CPAN
export PERL_MB_OPT="--installdirs=vendor --ccflags=-I/opt/include --lddlflags=-L/opt/lib --config installman1dir= --config installsiteman1dir= --config installman3dir= --config installsiteman3dir="
export PERL_MM_USE_DEFAULT=1
# install pre-installed modules
curl -fsSL --compressed http://cpanmin.us | perl -i -pe 's(^#!.*perl$)(#!/opt/bin/perl)' > /tmp/cpanm
install /tmp/cpanm /opt/bin/cpanm
curl -fsSL --compressed https://raw.githubusercontent.com/skaji/cpm/main/cpm | perl -i -pe 's(^#!.*perl$)(#!/opt/bin/perl)' > /tmp/cpm
install /tmp/cpm /opt/bin/cpm
# Net::SSLeay needs special CCFLAGS and LIBS to link
PERL_MM_OPT="INSTALLDIRS=vendor INSTALLMAN1DIR=none INSTALLMAN3DIR=none" /opt/bin/cpanm --notest "Net::SSLeay@$NET_SSLEAY_VERSION"
/opt/bin/cpanm --notest \
"Carton@$CARTON_VERSION" \
"AWS::XRay@$AWS_XRAY_VERSION" \
"JSON@$JSON_VERSION" \
"Cpanel::JSON::XS@$CPANEL_JSON_XS_VERSION" \
"JSON::XS@$JSON_XS_VERSION" \
"JSON::MaybeXS@$JSON_MAYBEXS_VERSION" \
"YAML@$YAML_VERSION" \
"YAML::Tiny@$YAML_TINY_VERSION" \
"YAML::XS@$YAML_XS_VERSION" \
"IO::Socket::SSL@$IO_SOCKET_SSL_VERSION" \
"Mozilla::CA@$MOZILLA_CA_VERSION" \
"local::lib@$LOCAL_LIB_VERSION"
/opt/bin/cpanm --notest .
# replace shebang to the absolute path of perl
cp script/bootstrap /opt/
perl -i -pe 's(^#!perl$)(#!/opt/bin/perl)' /opt/bootstrap
# remove POD(Plain Old Documentation)
dnf install -y perl-ExtUtils-MakeMaker
cd author/pod-stripper
perl /opt/bin/cpanm --installdeps --notest .
perl ./scripts/pod_stripper.pl /opt/lib/perl5
author/perl-stripper/template.yaml view on Meta::CPAN
Type: AWS::Serverless::Function
Metadata:
BuildMethod: makefile
Properties:
Description: Perl Stripper API
CodeUri: ./perl-stripper/
Handler: handler.handle
Runtime: provided.al2
Architectures: [arm64]
Timeout: 120
# https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html#configuration-memory-console
MemorySize: 1769 # -> 1 vCPU
Layers:
- arn:aws:lambda:ap-northeast-1:445285296882:layer:perl-5-38-runtime-al2-arm64:3
FunctionUrlConfig:
AuthType: NONE
author/update-aws-lambda-al.pl view on Meta::CPAN
runtime_arn => $runtime_arn,
runtime_version => (split /:/, $runtime_arn)[-1],
paws_arn => $paws_arn,
paws_version => (split /:/, $paws_arn)[-1],
}]);
}
}
$pm->wait_all_children;
chomp(my $module_version = `cat $FindBin::Bin/../META.json | jq -r .version`);
my $latest_perl = $versions->[0];
my $latest_perl_layer = $latest_perl =~ s/[.]/-/r;
my $latest_runtime_arn = $layers->{$latest_perl}{'us-east-1'}{runtime_arn};
my $latest_runtime_version = $layers->{$latest_perl}{'us-east-1'}{runtime_version};
my $latest_paws_arn = $layers->{$latest_perl}{'us-east-1'}{paws_arn};
my $latest_paws_version = $layers->{$latest_perl}{'us-east-1'}{paws_version};
open my $fh, '>', "$FindBin::Bin/../lib/AWS/Lambda/AL.pm" or die "$!";
sub printfh :prototype($) {
my $contents = shift;
$contents =~ s/\@\@VERSION\@\@/$module_version/g;
$contents =~ s/\@\@LATEST_PERL\@\@/$latest_perl/g;
$contents =~ s/\@\@LATEST_PERL_LAYER\@\@/$latest_perl_layer/g;
$contents =~ s/\@\@LATEST_RUNTIME_ARN\@\@/$latest_runtime_arn/g;
$contents =~ s/\@\@LATEST_RUNTIME_VERSION\@\@/$latest_runtime_version/g;
$contents =~ s/\@\@LATEST_PAWS_ARN\@\@/$latest_paws_arn/g;
$contents =~ s/\@\@LATEST_PAWS_VERSION\@\@/$latest_paws_version/g;
print $fh $contents;
}
printfh(<<'EOS');
package AWS::Lambda::AL;
use 5.026000;
use strict;
use warnings;
our $VERSION = "@@VERSION@@";
author/update-aws-lambda-al2.pl view on Meta::CPAN
runtime_version => (split /:/, $runtime_arn)[-1],
paws_arn => $paws_arn,
paws_version => (split /:/, $paws_arn)[-1],
}]);
}
}
}
$pm_al2->wait_all_children;
chomp(my $module_version = `cat $FindBin::Bin/../META.json | jq -r .version`);
my $latest_perl = $versions_al2->[0];
my $latest_perl_layer = $latest_perl =~ s/[.]/-/r;
my $latest_runtime_arn = $layers_al2->{$latest_perl}{'us-east-1'}{x86_64}{runtime_arn};
my $latest_runtime_version = $layers_al2->{$latest_perl}{'us-east-1'}{x86_64}{runtime_version};
my $latest_paws_arn = $layers_al2->{$latest_perl}{'us-east-1'}{x86_64}{paws_arn};
my $latest_paws_version = $layers_al2->{$latest_perl}{'us-east-1'}{x86_64}{paws_version};
open my $fh, '>', "$FindBin::Bin/../lib/AWS/Lambda/AL2.pm" or die "$!";
sub printfh :prototype($) {
my $contents = shift;
$contents =~ s/\@\@VERSION\@\@/$module_version/g;
$contents =~ s/\@\@LATEST_PERL\@\@/$latest_perl/g;
$contents =~ s/\@\@LATEST_PERL_LAYER\@\@/$latest_perl_layer/g;
$contents =~ s/\@\@LATEST_RUNTIME_ARN\@\@/$latest_runtime_arn/g;
$contents =~ s/\@\@LATEST_RUNTIME_VERSION\@\@/$latest_runtime_version/g;
$contents =~ s/\@\@LATEST_PAWS_ARN\@\@/$latest_paws_arn/g;
$contents =~ s/\@\@LATEST_PAWS_VERSION\@\@/$latest_paws_version/g;
print $fh $contents;
}
printfh(<<'EOS');
package AWS::Lambda::AL2;
use 5.026000;
use strict;
use warnings;
our $VERSION = "@@VERSION@@";
author/update-aws-lambda-al2023.pl view on Meta::CPAN
runtime_version => (split /:/, $runtime_arn)[-1],
paws_arn => $paws_arn,
paws_version => (split /:/, $paws_arn)[-1],
}]);
}
}
}
$pm_al2023->wait_all_children;
chomp(my $module_version = `cat $FindBin::Bin/../META.json | jq -r .version`);
my $latest_perl = $versions_al2023->[0];
my $latest_perl_layer = $latest_perl =~ s/[.]/-/r;
my $latest_runtime_arn = $layers_al2023->{$latest_perl}{'us-east-1'}{x86_64}{runtime_arn};
my $latest_runtime_version = $layers_al2023->{$latest_perl}{'us-east-1'}{x86_64}{runtime_version};
my $latest_paws_arn = $layers_al2023->{$latest_perl}{'us-east-1'}{x86_64}{paws_arn};
my $latest_paws_version = $layers_al2023->{$latest_perl}{'us-east-1'}{x86_64}{paws_version};
open my $fh, '>', "$FindBin::Bin/../lib/AWS/Lambda/AL2023.pm" or die "$!";
sub printfh :prototype($) {
my $contents = shift;
$contents =~ s/\@\@VERSION\@\@/$module_version/g;
$contents =~ s/\@\@LATEST_PERL\@\@/$latest_perl/g;
$contents =~ s/\@\@LATEST_PERL_LAYER\@\@/$latest_perl_layer/g;
$contents =~ s/\@\@LATEST_RUNTIME_ARN\@\@/$latest_runtime_arn/g;
$contents =~ s/\@\@LATEST_RUNTIME_VERSION\@\@/$latest_runtime_version/g;
$contents =~ s/\@\@LATEST_PAWS_ARN\@\@/$latest_paws_arn/g;
$contents =~ s/\@\@LATEST_PAWS_VERSION\@\@/$latest_paws_version/g;
print $fh $contents;
}
printfh(<<'EOS');
package AWS::Lambda::AL2023;
use 5.026000;
use strict;
use warnings;
our $VERSION = "@@VERSION@@";
requires 'JSON::XS', '4.0';
requires 'Try::Tiny', '0.30';
requires 'Plack', '1.0047';
requires 'Plack::Middleware::ReverseProxy', '0.16';
requires 'JSON::Types', '0.05';
requires 'URI::Escape';
requires 'MIME::Base64';
recommends 'AWS::XRay', '>=0.09';
on 'test' => sub {
requires 'Test::More', '0.98';
requires 'Test::Deep', '1.128';
requires 'Test::TCP', '2.19';
requires 'Test::SharedFork';
requires 'Test::Warn';
requires 'File::Slurp', '9999.25';
requires 'Starman';
};
on 'develop' => sub {
examples/cgi/WwwCounter/Makefile view on Meta::CPAN
.PHONY: build-WwwCounter
build-WwwCounter: $(ARTIFACTS_DIR)/cpanfile
cp -r *.* $(ARTIFACTS_DIR)
$(ARTIFACTS_DIR)/cpanfile: cpanfile
cp -r cpanfile $(ARTIFACTS_DIR)
docker run --rm -v $(ARTIFACTS_DIR):/var/task shogo82148/p5-aws-lambda:build-5.34.al2 \
cpanm --notest -L local --installdeps .
examples/cgi/WwwCounter/readme.html view on Meta::CPAN
</ol>
</div>
<h4>â <a name="Trouble">åããªãã¨ãã¯</a></h4>
<div class=i>
<p>ã«ã¦ã³ã¿ã¼ããã¾ãåããªãæã¯ä»¥ä¸ã®æé ã«å¾ã£ã¦èª¿ã¹ã¦è¦ã¦ãã ããã</p>
<ol>
<li><p><b>ãã¹ãï¼</b><br>
ã<a href="http://www.tohoho-web.com/wwwcgi.htm">ã¨ã»ã»ã®CGIå
¥é</a>ãã®ãCGIã®è¨ç½®æ¹æ³ãã«å¾ã£ã¦ãç°¡åãªCGIãåä½ãããã©ãã確èªãã¦ãã ããã</p></li>
<li><p><b>ãã¹ãï¼</b><br>
ãã©ã¦ã¶ã®[ãã¡ã¤ã«]â[(å ´æãæå®ãã¦)éã] ããããhttp://ï½/ï½/wwwcount.cgi?testãã¨å
¥åãã¦ãéãã¦ãã ããããï½ãã®é¨åã«ã¯é©åãªãµã¼ãã¼åããã©ã«ãåãæå®ãã¦ãã ãããC...
<ul>
<li>http://ï½ ã§å§ã¾ãã¢ãã¬ã¹ã§ã¢ã¯ã»ã¹ãã¦ããªãã
<li>ãµã¼ãã¼ãCGIããµãã¼ããã¦ããªãã
<li>1è¡ç®ã® #! ã®åã«ç©ºç½æåã空è¡ãã´ããããã
<li>1è¡ç®ã® perl ã®ãã¹åãé©åã§ãªãã
<li>wwwcount.cgi ã®æ¹è¡ã³ã¼ããé©åã§ãªãã
<li>wwwcount.cgi ã®ãã¼ããã·ã§ã³ãé©åã§ãªãã
</ul>
<br>
</li>
examples/cgi/WwwCounter/sample.html view on Meta::CPAN
<style>
.i { margin-left: 1rem; }
</style>
</head>
<body>
<h2 align="center">WwwCounterãµã³ãã«</h2>
<hr>
<h4>è¨ç½®ãã¹ã</h4>
<div class="i">
<a href="wwwcount.cgi?test">wwwcount.cgi?test</a>
</div>
<h4>CGIã°ã©ãã£ãã¯ã«ã¦ã³ã¿ã¼</h4>
<div class="i">
ããªãã¯
<img src="wwwcount.cgi?gif" width=96 height=18 alt="Counter">
人ç®ã®ã客æ§ã§ãã
</div>
<h4>SSIããã¹ãã«ã¦ã³ã¿ã¼</h4>
examples/cgi/WwwCounter/wwwcount.cgi view on Meta::CPAN
# åç§°ï¼ WwwCount 4.0
# ä½è
ï¼ æç«ã
# ææ°çå
¥æå
ï¼ https://www.tohoho-web.com/wwwsoft.htm
# åãæ±ãï¼ ããªã¼ã½ãããå©ç¨/æ¹é /åé
å¸å¯è½ã確èªã¡ã¼ã«ä¸è¦ã
# è使¨©ï¼Copyright (C) 1996-2021 æç«ã
#==================================================================
#==================================================================
# 使ãããï¼
#==================================================================
# (æ¸å¼1) wwwcount.cgi?test
# CGIã使ç¨ã§ããããã¹ããè¡ãã
#
# (æ¸å¼2) wwwcount.cgi?text
# ã«ã¦ã³ãã¢ãããè¡ããã«ã¦ã³ã¿ãããã¹ãã§è¡¨ç¤ºããã
#
# (æ¸å¼3) wwwcount.cgi?gif
# ã«ã¦ã³ãã¢ãããè¡ããã«ã¦ã³ã¿ãGIFã§è¡¨ç¤ºããã
#
# (æ¸å¼4) wwwcount.cgi?hide+xxx.gif
# ã«ã¦ã³ãã¢ãããè¡ããxxx.gifã表示ããã
examples/cgi/WwwCounter/wwwcount.cgi view on Meta::CPAN
# ã«ã¬ã³ããã©ã«ãã夿´ããã
if ($g_chdir ne "") {
chdir($g_chdir);
}
# 弿°ãè§£éãã
parseArguments();
# ãã¹ãã¢ã¼ãã§ããã°ãã¹ããå¼ã³åºã
if ($g_mode eq "test") {
test();
exit(0);
}
# ããã¯ãããã
doLock();
# ã«ã¦ã³ã¿ã¼ãèªã¿ã ã
$count = readCount();
# æçµã¢ã¯ã»ã¹æ¥ãèªã¿ã ã
examples/cgi/WwwCounter/wwwcount.cgi view on Meta::CPAN
}
#
# 弿°ãè§£éãã
#
sub parseArguments {
my(@argv) = split(/\+/, $ENV{'QUERY_STRING'});
for (my $i = 0; $i <= $#argv; $i++) {
# ãã¹ãã¢ã¼ã
if ($argv[$i] eq "test") {
$g_mode = "test";
# ããã¹ãã¢ã¼ã
} elsif ($argv[$i] eq "text") {
$g_mode = "text";
# GIFã¢ã¼ã
} elsif ($argv[$i] eq "gif") {
$g_mode = "gif";
# é ãã«ã¦ã³ã¿ã¼ã¢ã¼ã
examples/cgi/WwwCounter/wwwcount.cgi view on Meta::CPAN
#
sub unlockLock {
if ($g_lock_flag) {
rmdir($g_file_lock);
}
}
#
# CGIã使ç¨ã§ããããã¹ããè¡ãã
#
sub test {
print "Content-type: text/html\n";
print "\n";
print "<!doctype html>\n";
print "<html>\n";
print "<head>\n";
print "<meta charset='utf-8'>\n";
print "<title>Test</title>\n";
print "</head>\n";
print "<body>\n";
print "<p>OK. CGIã¹ã¯ãªããã¯æ£å¸¸ã«åãã¦ãã¾ãã</p>\n";
examples/custom-docker/Dockerfile view on Meta::CPAN
FROM perl:5.32-slim-buster
RUN mkdir -p /var/task \
&& apt-get update \
&& apt-get install -y --no-install-recommends gcc libc6-dev \
&& cpanm --notest AWS::Lambda \
&& apt-get purge -y --auto-remove gcc libc6-dev \
&& rm -fr /var/cache/apt/* /var/lib/apt/lists/* \
&& rm -fr ./cpanm /root/.cpanm /tmp/*
COPY handler.pl /var/task/
WORKDIR /var/task
ENTRYPOINT [ "/usr/local/bin/perl", "-MAWS::Lambda::Bootstrap", "-e", "bootstrap(@ARGV)" ]
CMD [ "handler.handle" ]
examples/custom-docker/README.md view on Meta::CPAN
# An Example of Custom Docker Images
Build the hello-perl container image locally:
$ docker build -t hello-perl .
To upload the container image, you need to create a new ECR repository in your account and tag the local image to push it to ECR.
$ aws ecr create-repository --repository-name hello-perl --image-scanning-configuration scanOnPush=true
$ docker tag hello-perl:latest 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
$ aws ecr get-login-password | docker login --username AWS --password-stdin 123412341234.dkr.ecr.sa-east-1.amazonaws.com
$ docker push 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
Finally, create new function using awscli.
$ aws --region "$REGION" --profile "$PROFILE" lambda create-function \
--function-name "hello-perl" \
--code ImageUri=123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest \
--handler "handler.handle" \
--runtime provided.al2 \
--role arn:aws:iam::xxxxxxxxxxxx:role/service-role/lambda-custom-runtime-perl-role
examples/docker/README.md view on Meta::CPAN
# An Example of Using Prebuilt Docker Images
Build the hello-perl container image locally:
$ docker build -t hello-perl .
To check if this is working, start the container image locally using the Lambda Runtime Interface Emulator:
$ docker run -p 9000:8080 hello-perl:latest
Now, you can test a function invocation with cURL.
$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
To upload the container image, you need to create a new ECR repository in your account and tag the local image to push it to ECR.
$ aws ecr create-repository --repository-name hello-perl --image-scanning-configuration scanOnPush=true
$ docker tag hello-perl:latest 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
$ aws ecr get-login-password | docker login --username AWS --password-stdin 123412341234.dkr.ecr.sa-east-1.amazonaws.com
$ docker push 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
Finally, create new function using awscli.
$ aws --region "$REGION" --profile "$PROFILE" lambda create-function \
--function-name "hello-perl" \
--code ImageUri=123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest \
--handler "handler.handle" \
--runtime provided.al2 \
--role arn:aws:iam::xxxxxxxxxxxx:role/service-role/lambda-custom-runtime-perl-role
examples/hello/Makefile view on Meta::CPAN
build: hello.zip
hello.zip: handler.pl cpanfile
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:build-5.32.al2 \
cpanm --notest -L extlocal --installdeps .
zip -r hello.zip . -x '*.zip'
test:
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:5.32.al2 \
handler.handle '{}'
clean:
rm -f hello.zip
rm -rf local
rm -rf extlocal
.PHONY: build test clean
examples/psgi/Makefile view on Meta::CPAN
build: psgi.zip
psgi.zip: handler.pl cpanfile app.psgi
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:build-5.32.al2 \
cpanm --notest -L extlocal --installdeps .
zip -r psgi.zip . -x '*.zip'
test:
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:5.32.al2 \
handler.handle '{"httpMethod": "GET", "path":"/"}'
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:5.32.al2 \
handler.handle '{"httpMethod": "POST", "path":"/foo", "headers": {"Content-Type": "application/json"}, "body":"{\"hello\":\"lambda\"}"}'
clean:
rm -f psgi.zip
rm -rf local
rm -rf extlocal
.PHONY: build test clean
examples/s3-get-object/Makefile view on Meta::CPAN
build: s3-get-object.zip
s3-get-object.zip: handler.pl cpanfile
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:build-5.32-paws.al2 \
cpanm --notest --local-lib extlocal --no-man-pages --installdeps .
zip -r s3-get-object.zip . -x '*.zip'
clean:
rm -f s3-get-object.zip
rm -rf local
rm -rf extlocal
.PHONY: build clean
lib/AWS/Lambda.pm view on Meta::CPAN
Finally, create new function using awscli.
$ aws --region "$REGION" --profile "$PROFILE" lambda create-function \
--function-name "hello-perl" \
--zip-file "fileb://handler.zip" \
--handler "handler.handle" \
--runtime provided.al2023 \
--role arn:aws:iam::xxxxxxxxxxxx:role/service-role/lambda-custom-runtime-perl-role \
--layers "arn:aws:lambda:$REGION:445285296882:layer:perl-5-38-runtime-al2023-x86_64:1"
It also supports L<response streaming|https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html>.
sub handle {
my ($payload, $context) = @_;
return sub {
my $responder = shift;
my $writer = $responder->('application/json');
$writer->write('{"foo": "bar"}');
$writer->close;
};
}
lib/AWS/Lambda.pm view on Meta::CPAN
# FROM public.ecr.aws/shogo82148/p5-aws-lambda:base-5.38.al2023
COPY handler.pl /var/task/
CMD [ "handler.handle" ]
Build the hello-perl container image locally:
$ docker build -t hello-perl .
To check if this is working, start the container image locally using the Lambda Runtime Interface Emulator:
$ docker run -p 9000:8080 hello-perl:latest
Now, you can test a function invocation with cURL.
$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
To upload the container image, you need to create a new ECR repository in your account and tag the local image to push it to ECR.
$ aws ecr create-repository --repository-name hello-perl --image-scanning-configuration scanOnPush=true
$ docker tag hello-perl:latest 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
$ aws ecr get-login-password | docker login --username AWS --password-stdin 123412341234.dkr.ecr.sa-east-1.amazonaws.com
$ docker push 123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest
Finally, create new function using awscli.
$ aws --region "$REGION" --profile "$PROFILE" lambda create-function \
--function-name "hello-perl" \
--code ImageUri=123412341234.dkr.ecr.sa-east-1.amazonaws.com/hello-perl:latest \
--handler "handler.handle" \
--runtime provided.al2023 \
--role arn:aws:iam::xxxxxxxxxxxx:role/service-role/lambda-custom-runtime-perl-role
=head2 Run in Local using Docker
Prebuilt Docker Images based on L<https://hub.docker.com/r/lambci/lambda/> are available.
You can pull from L<https://gallery.ecr.aws/shogo82148/p5-aws-lambda> or L<https://hub.docker.com/r/shogo82148/p5-aws-lambda>,
and build zip archives to deploy.
# Install the dependency.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:build-5.38.al2023 \
cpanm --notest --local-lib extlocal --no-man-pages --installdeps .
# run an event.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:5.38.al2023 \
handler.handle '{"some":"event"}'
=head2 Pre-installed modules
The following modules are pre-installed for convenience.
=over
lib/AWS/Lambda.pm view on Meta::CPAN
# FROM public.ecr.aws/shogo82148/p5-aws-lambda:base-5.38-paws.al2023
COPY handler.pl /var/task/
CMD [ "handler.handle" ]
=head2 Run in Local using Docker for Paws
use the C<build-$VERSION-paws.al2023> and C<$VERSION-paws.al2023> tag on L<https://gallery.ecr.aws/shogo82148/p5-aws-lambda> or L<https://hub.docker.com/r/shogo82148/p5-aws-lambda>.
# Install the dependency.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:build-5.38-paws.al2023 \
cpanm --notest --local-lib extlocal --no-man-pages --installdeps .
# run an event.
docker run --rm -v $(PWD):/var/task shogo82148/p5-aws-lambda:5.38-paws.al2023 \
handler.handle '{"some":"event"}'
=head1 CREATE MODULE LAYER
To create custom module layer such as the Paws Layer,
install the modules into C</opt/lib/perl5/site_perl> in the layer.
# Create Some::Module Layer
docker run --rm \
-v $(PWD):/var/task \
-v $(PATH_TO_LAYER_DIR)/lib/perl5/site_perl:/opt/lib/perl5/site_perl \
shogo82148/p5-aws-lambda:build-5.38.al2023 \
cpanm --notest --no-man-pages Some::Module
cd $(PATH_TO_LAYER_DIR) && zip -9 -r $(PATH_TO_DIST)/some-module.zip .
=head1 MAINTENANCE AND SUPPORT
Supported Perl versions are the same as those officially supported by the Perl community (L<perlpolicy>).
It means that we support the two most recent stable release series.
=head1 LEGACY CUSTOM RUNTIME ON AMAZON LINUX
We also provide the layers for legacy custom runtime as known as "provided".
lib/AWS/Lambda/Bootstrap.pm view on Meta::CPAN
my ($payload, $context) = @_;
# handle the event here.
my $result = {};
return $result;
}
C<$context> is an instance of L<AWS::Lambda::Context>.
=head1 RESPONSE STREAMING
It also supports L<response streaming|https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html>.
sub handle {
my ($payload, $context) = @_;
return sub {
my $responder = shift;
my $writer = $responder->('application/json');
$writer->write('{"foo": "bar"}');
$writer->close;
};
}
lib/AWS/Lambda/PSGI.pm view on Meta::CPAN
my $input = $self->format_input($env, $ctx);
my $res = $self->app->($input);
return $self->format_output($res);
}
}
sub format_input {
my ($self, $payload, $ctx) = @_;
if (my $context = $payload->{requestContext}) {
if ($context->{elb}) {
# Application Load Balancer https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html
return $self->_format_input_v1($payload, $ctx);
}
}
if (my $version = $payload->{version}) {
if ($version =~ /^1[.]/) {
# API Gateway for REST https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
return $self->_format_input_v1($payload, $ctx);
}
if ($version =~ /^2[.]/) {
# API Gateway for HTTP https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
return $self->_format_input_v2($payload, $ctx);
}
}
return $self->_format_input_v1($payload, $ctx);
}
sub _format_input_v1 {
my ($self, $payload, $ctx) = @_;
my $env = {};
lib/AWS/Lambda/PSGI.pm view on Meta::CPAN
my $app = require "$ENV{'LAMBDA_TASK_ROOT'}/app.psgi";
my $func = AWS::Lambda::PSGI->wrap($app);
sub handle {
return $func->(@_);
}
1;
And then, L<Set up Lambda Proxy Integrations in API Gateway|https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html> or
L<Lambda Functions as ALB Targets|https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html>
=head1 DESCRIPTION
=head2 Streaming Response
L<AWS::Lambda::PSGI> supports L<response streaming|https://docs.aws.amazon.com/lambda/latest/dg/configuration-response-streaming.html>.
The function urls's invoke mode is configured as C<"RESPONSE_STREAM">, and Lambda environment variable "PERL5_LAMBDA_PSGI_INVOKE_MODE" is set to C<"RESPONSE_STREAM">.
ExampleApi:
Type: AWS::Serverless::Function
Properties:
FunctionUrlConfig:
AuthType: NONE
InvokeMode: RESPONSE_STREAM
Environment:
Variables:
t/00_compile.t view on Meta::CPAN
use_ok $_ for qw(
AWS::Lambda
AWS::Lambda::AL
AWS::Lambda::AL2
AWS::Lambda::AL2023
AWS::Lambda::Bootstrap
AWS::Lambda::Context
AWS::Lambda::PSGI
);
done_testing;
t/01_echo.t view on Meta::CPAN
my $dummy_context = AWS::Lambda::Context->new(
deadline_ms => 1000,
aws_request_id => '8476a536-e9f4-11e8-9739-2dfe598c3fcd',
invoked_function_arn => 'arn:aws:lambda:us-east-2:123456789012:function:custom-runtime',
trace_id => "Root=1-5bef4de7-ad49b0e87f6ef6c87fc2e700;Parent=9a9197af755a6419;Sampled=1",
);
my $bootstrap = BootstrapMock->new(
handler => "echo.handle",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
lambda_next => sub {
return $payload, $dummy_context;
},
lambda_response => sub {
my $self = shift;
$response = shift;
$context = shift;
},
);
ok $bootstrap->handle_event;
cmp_deeply $response, $payload, "echo handler";
is $context, $dummy_context, "context";
done_testing;
t/02_error.t view on Meta::CPAN
use Test::More;
use FindBin;
use lib "$FindBin::Bin/lib";
use BootstrapMock;
my $error;
my $bootstrap = BootstrapMock->new(
handler => "error.handle",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
lambda_next => sub {
return +{
key1 => 1,
key2 => 2,
key3 => 3,
}, undef;
},
lambda_error => sub {
my $self = shift;
$error = shift;
},
);
ok !$bootstrap->handle_event;
like $error, qr/some error/;
done_testing;
t/03_init_error.t view on Meta::CPAN
use FindBin;
use lib "$FindBin::Bin/lib";
use BootstrapMock;
use AWS::Lambda::Context;
use Try::Tiny;
my $error;
my $bootstrap = BootstrapMock->new(
handler => "init_error.handle",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
lambda_init_error => sub {
my $self = shift;
$error = shift;
},
);
ok !$bootstrap->handle_event;
like $error, qr/did not return a true value/;
done_testing;
t/04_handler_not_found.t view on Meta::CPAN
use FindBin;
use lib "$FindBin::Bin/lib";
use BootstrapMock;
use AWS::Lambda::Context;
use Try::Tiny;
my $error;
my $bootstrap = BootstrapMock->new(
handler => "echo.handle_not_found",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
lambda_init_error => sub {
my $self = shift;
$error = shift;
},
);
ok !$bootstrap->handle_event;
like $error, qr/handler handle_not_found is not found/;
done_testing;