AWS-Lambda

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

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

META.json  view on Meta::CPAN

            "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"
         }
      }

README.md  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 [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;
        };
    }

README.md  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

## 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)

README.md  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" ]

## 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@@";

cpanfile  view on Meta::CPAN

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>テスト1</b><br>
「<a href="http://www.tohoho-web.com/wwwcgi.htm">とほほのCGI入門</a>」の「CGIの設置方法」に従って、簡単なCGIが動作するかどうか確認してください。</p></li>
<li><p><b>テスト2</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;



( run in 0.517 second using v1.01-cache-2.11-cpan-87723dcf8b7 )