├── lib └── resty │ └── aws │ ├── .keep │ ├── cred.lua │ ├── request.lua │ ├── signature.lua │ ├── sqs.lua │ ├── sns.lua │ └── lambda.lua ├── .gitignore ├── scripts └── busted ├── .gitmodules ├── codegen ├── main.lua ├── Makefile ├── tpl.lua ├── method_tpl.lua └── service.lua ├── lua-resty-aws-sdk-0.1-0.src.rock ├── test ├── aws4_testsuite │ ├── get-vanilla │ │ ├── get-vanilla.req │ │ ├── get-vanilla.sts │ │ ├── get-vanilla.creq │ │ ├── get-vanilla.authz │ │ └── get-vanilla.sreq │ ├── post-vanilla │ │ ├── post-vanilla.req │ │ ├── post-vanilla.sts │ │ ├── post-vanilla.creq │ │ ├── post-vanilla.authz │ │ └── post-vanilla.sreq │ ├── get-vanilla-query │ │ ├── get-vanilla-query.req │ │ ├── get-vanilla-query.sts │ │ ├── get-vanilla-query.creq │ │ ├── get-vanilla-query.authz │ │ └── get-vanilla-query.sreq │ ├── normalize-path │ │ ├── get-slash │ │ │ ├── get-slash.req │ │ │ ├── get-slash.sts │ │ │ ├── get-slash.creq │ │ │ ├── get-slash.authz │ │ │ └── get-slash.sreq │ │ ├── get-relative │ │ │ ├── get-relative.req │ │ │ ├── get-relative.sts │ │ │ ├── get-relative.creq │ │ │ ├── get-relative.authz │ │ │ └── get-relative.sreq │ │ ├── get-slashes │ │ │ ├── get-slashes.req │ │ │ ├── get-slashes.sts │ │ │ ├── get-slashes.creq │ │ │ ├── get-slashes.authz │ │ │ └── get-slashes.sreq │ │ ├── get-space │ │ │ ├── get-space.req │ │ │ ├── get-space.sts │ │ │ ├── get-space.authz │ │ │ ├── get-space.creq │ │ │ └── get-space.sreq │ │ ├── get-slash-dot-slash │ │ │ ├── get-slash-dot-slash.req │ │ │ ├── get-slash-dot-slash.sts │ │ │ ├── get-slash-dot-slash.creq │ │ │ ├── get-slash-dot-slash.authz │ │ │ └── get-slash-dot-slash.sreq │ │ ├── get-slash-pointless-dot │ │ │ ├── get-slash-pointless-dot.req │ │ │ ├── get-slash-pointless-dot.sts │ │ │ ├── get-slash-pointless-dot.creq │ │ │ ├── get-slash-pointless-dot.authz │ │ │ └── get-slash-pointless-dot.sreq │ │ ├── get-relative-relative │ │ │ ├── get-relative-relative.req │ │ │ ├── get-relative-relative.sts │ │ │ ├── get-relative-relative.creq │ │ │ ├── get-relative-relative.authz │ │ │ └── get-relative-relative.sreq │ │ └── normalize-path.txt │ ├── post-header-key-case │ │ ├── post-header-key-case.req │ │ ├── post-header-key-case.sts │ │ ├── post-header-key-case.creq │ │ ├── post-header-key-case.authz │ │ └── post-header-key-case.sreq │ ├── get-vanilla-utf8-query │ │ ├── get-vanilla-utf8-query.req │ │ ├── get-vanilla-utf8-query.sts │ │ ├── get-vanilla-utf8-query.authz │ │ ├── get-vanilla-utf8-query.creq │ │ └── get-vanilla-utf8-query.sreq │ ├── post-vanilla-query │ │ ├── post-vanilla-query.req │ │ ├── post-vanilla-query.sts │ │ ├── post-vanilla-query.creq │ │ ├── post-vanilla-query.authz │ │ └── post-vanilla-query.sreq │ ├── post-sts-token │ │ ├── post-sts-header-after │ │ │ ├── post-sts-header-after.req │ │ │ ├── post-sts-header-after.sts │ │ │ ├── post-sts-header-after.creq │ │ │ ├── post-sts-header-after.authz │ │ │ └── post-sts-header-after.sreq │ │ ├── post-sts-header-before │ │ │ ├── post-sts-header-before.sts │ │ │ ├── post-sts-header-before.authz │ │ │ ├── post-sts-header-before.req │ │ │ ├── post-sts-header-before.creq │ │ │ └── post-sts-header-before.sreq │ │ └── readme.txt │ ├── post-header-key-sort │ │ ├── post-header-key-sort.req │ │ ├── post-header-key-sort.sts │ │ ├── post-header-key-sort.authz │ │ ├── post-header-key-sort.creq │ │ └── post-header-key-sort.sreq │ ├── get-vanilla-empty-query-key │ │ ├── get-vanilla-empty-query-key.req │ │ ├── get-vanilla-empty-query-key.sts │ │ ├── get-vanilla-empty-query-key.authz │ │ ├── get-vanilla-empty-query-key.creq │ │ └── get-vanilla-empty-query-key.sreq │ ├── post-header-value-case │ │ ├── post-header-value-case.req │ │ ├── post-header-value-case.sts │ │ ├── post-header-value-case.authz │ │ ├── post-header-value-case.creq │ │ └── post-header-value-case.sreq │ ├── post-vanilla-empty-query-value │ │ ├── post-vanilla-empty-query-value.req │ │ ├── post-vanilla-empty-query-value.sts │ │ ├── post-vanilla-empty-query-value.authz │ │ ├── post-vanilla-empty-query-value.creq │ │ └── post-vanilla-empty-query-value.sreq │ ├── get-unreserved │ │ ├── get-unreserved.req │ │ ├── get-unreserved.sts │ │ ├── get-unreserved.authz │ │ ├── get-unreserved.creq │ │ └── get-unreserved.sreq │ ├── get-vanilla-query-order-key-case │ │ ├── get-vanilla-query-order-key-case.req │ │ ├── get-vanilla-query-order-key-case.sts │ │ ├── get-vanilla-query-order-key-case.authz │ │ ├── get-vanilla-query-order-key-case.creq │ │ └── get-vanilla-query-order-key-case.sreq │ ├── get-header-key-duplicate │ │ ├── get-header-key-duplicate.req │ │ ├── get-header-key-duplicate.sts │ │ ├── get-header-key-duplicate.authz │ │ ├── get-header-key-duplicate.creq │ │ └── get-header-key-duplicate.sreq │ ├── get-header-value-order │ │ ├── get-header-value-order.sts │ │ ├── get-header-value-order.req │ │ ├── get-header-value-order.authz │ │ ├── get-header-value-order.creq │ │ └── get-header-value-order.sreq │ ├── post-x-www-form-urlencoded │ │ ├── post-x-www-form-urlencoded.sts │ │ ├── post-x-www-form-urlencoded.req │ │ ├── post-x-www-form-urlencoded.authz │ │ ├── post-x-www-form-urlencoded.creq │ │ └── post-x-www-form-urlencoded.sreq │ ├── get-vanilla-query-unreserved │ │ ├── get-vanilla-query-unreserved.sts │ │ ├── get-vanilla-query-unreserved.authz │ │ ├── get-vanilla-query-unreserved.req │ │ ├── get-vanilla-query-unreserved.creq │ │ └── get-vanilla-query-unreserved.sreq │ └── post-x-www-form-urlencoded-parameters │ │ ├── post-x-www-form-urlencoded-parameters.sts │ │ ├── post-x-www-form-urlencoded-parameters.req │ │ ├── post-x-www-form-urlencoded-parameters.authz │ │ ├── post-x-www-form-urlencoded-parameters.creq │ │ └── post-x-www-form-urlencoded-parameters.sreq └── request_spec.lua ├── .editorconfig ├── Makefile ├── lua-resty-aws-sdk-0.1-0.rockspec ├── examples └── lambda_no_body.lua ├── src ├── cred.lua ├── request.lua └── signature.lua └── README.md /lib/resty/aws/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/try.lua 2 | try.lua 3 | try2.lua 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /scripts/busted: -------------------------------------------------------------------------------- 1 | #!/usr/local/openresty/bin/resty 2 | 3 | require 'busted.runner'({ standalone = false }) 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "codegen/botocore"] 2 | path = codegen/botocore 3 | url = git@github.com:boto/botocore.git 4 | -------------------------------------------------------------------------------- /codegen/main.lua: -------------------------------------------------------------------------------- 1 | #!/usr/local/openresty/bin/resty 2 | 3 | local render = require 'service' 4 | 5 | print(render(arg[1])) 6 | -------------------------------------------------------------------------------- /lua-resty-aws-sdk-0.1-0.src.rock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiddkai/lua-resty-aws-sdk/HEAD/lua-resty-aws-sdk-0.1-0.src.rock -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla/get-vanilla.req: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla/post-vanilla.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query/get-vanilla-query.req: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash/get-slash.req: -------------------------------------------------------------------------------- 1 | GET // HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-case/post-header-key-case.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-utf8-query/get-vanilla-utf8-query.req: -------------------------------------------------------------------------------- 1 | GET /?ሴ=bar HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative/get-relative.req: -------------------------------------------------------------------------------- 1 | GET /example/.. HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slashes/get-slashes.req: -------------------------------------------------------------------------------- 1 | GET //example// HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-space/get-space.req: -------------------------------------------------------------------------------- 1 | GET /example space/ HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-query/post-vanilla-query.req: -------------------------------------------------------------------------------- 1 | POST /?Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.req: -------------------------------------------------------------------------------- 1 | GET /./ HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-after/post-sts-header-after.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-sort/post-header-key-sort.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:value1 4 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.req: -------------------------------------------------------------------------------- 1 | GET /?Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.req: -------------------------------------------------------------------------------- 1 | GET /./example HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-value-case/post-header-value-case.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:VALUE1 4 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.req: -------------------------------------------------------------------------------- 1 | POST /?Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative-relative/get-relative-relative.req: -------------------------------------------------------------------------------- 1 | GET /example1/example2/../.. HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/get-unreserved/get-unreserved.req: -------------------------------------------------------------------------------- 1 | GET /-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.req: -------------------------------------------------------------------------------- 1 | GET /?Param2=value2&Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla/get-vanilla.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-unreserved/get-unreserved.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 6a968768eefaa713e2a6b16b589a8ea192661f098f37349f4e2c0082757446f9 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla/post-vanilla.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 553f88c9e4d10fc9e109e2aeb65f030801b70c2f6468faca261d401ae622fc87 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash/get-slash.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-space/get-space.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 63ee75631ed7234ae61b5f736dfc7754cdccfedbff4b5128a915706ee9390d86 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query/get-vanilla-query.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slashes/get-slashes.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | cb96b4ac96d501f7c5c15bc6d67b3035061cfced4af6585ad927f7e6c985c015 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-query/post-vanilla-query.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 9d659678c1756bb3113e2ce898845a0a79dbbc57b740555917687f1b3340fbbd -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-key-duplicate/get-header-key-duplicate.req: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:value2 4 | My-Header1:value2 5 | My-Header1:value1 6 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative/get-relative.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-case/post-header-key-case.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 553f88c9e4d10fc9e109e2aeb65f030801b70c2f6468faca261d401ae622fc87 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-sort/post-header-key-sort.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 9368318c2967cf6de74404b30c65a91e8f6253e0a8659d6d5319f1a812f87d65 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-key-duplicate/get-header-key-duplicate.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | dc7f04a3abfde8d472b0ab1a418b741b7c67174dad1551b4117b15527fbe966c -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-value-order/get-header-value-order.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 31ce73cd3f3d9f66977ad3dd957dc47af14df92fcd8509f59b349e9137c58b86 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-utf8-query/get-vanilla-utf8-query.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | eb30c5bed55734080471a834cc727ae56beb50e5f39d1bff6d0d38cb192a7073 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla/get-vanilla.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-value-case/post-header-value-case.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | d51ced243e649e3de6ef63afbbdcbca03131a21a7103a1583706a64618606a93 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla/post-vanilla.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 42a5e5bb34198acb3e84da4f085bb7927f2bc277ca766e6d19c73c2154021281 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 1e24db194ed7d0eec2de28d7369675a243488e08526e8c1c73571282f7c517ab -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | c30d4703d9f799439be92736156d47ccfb2d879ddf56f5befa6d1d6aab979177 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query/get-vanilla-query.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative-relative/get-relative-relative.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash/get-slash.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-after/post-sts-header-after.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 553f88c9e4d10fc9e109e2aeb65f030801b70c2f6468faca261d401ae622fc87 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Content-Type:application/x-www-form-urlencoded 3 | Host:example.amazonaws.com 4 | X-Amz-Date:20150830T123600Z 5 | 6 | Param1=value1 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-value-order/get-header-value-order.req: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:value4 4 | My-Header1:value1 5 | My-Header1:value3 6 | My-Header1:value2 7 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla/get-vanilla.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative/get-relative.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 214d50c111a8edc4819da6a636336472c916b5240f51e9a51b5c3305180cf702 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-case/post-header-key-case.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-before/post-sts-header-before.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | c237e1b440d4c63c32ca95b5b99481081cb7b13c7e40434868e71567c1a882f6 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 9d659678c1756bb3113e2ce898845a0a79dbbc57b740555917687f1b3340fbbd -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla/post-vanilla.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5da7c1a2acd57cee7505fc6676e4e544621c30862966e37dddb68e92efbe5d6b -------------------------------------------------------------------------------- /test/aws4_testsuite/get-unreserved/get-unreserved.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=07ef7494c76fa4850883e2b006601f940f8a34d404d0cfa977f52a65bbf5f24f -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 816cd5b414d056048ba4f7c5386d6e0533120fb1fcfa93762cf0fc39e2cf19e0 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slashes/get-slashes.creq: -------------------------------------------------------------------------------- 1 | GET 2 | /example/ 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query/get-vanilla-query.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash/get-slash.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-space/get-space.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=652487583200325589f1fba4c7e578f72c47cb61beeca81406b39ddec1366741 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-space/get-space.creq: -------------------------------------------------------------------------------- 1 | GET 2 | /example%20space/ 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-query/post-vanilla-query.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | Param1=value1 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative/get-relative.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slashes/get-slashes.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9a624bd73a37c9a373b5312afbebe7a714a789de108f0bdfe846570885f57e84 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-case/post-header-key-case.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5da7c1a2acd57cee7505fc6676e4e544621c30862966e37dddb68e92efbe5d6b -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-query/post-vanilla-query.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=28038455d6de14eafc1f9222cf5aa6f1a96197d7deb8263271d420d138af7f11 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.sts: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 2 | 20150830T123600Z 3 | 20150830/us-east-1/service/aws4_request 4 | 2e1cf7ed91881a30569e46552437e4156c823447bf1781b921b5d486c568dd1c -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-utf8-query/get-vanilla-utf8-query.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=2cdec8eed098649ff3a119c94853b13c643bcf08f8b0a1d91e12c9027818dd04 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-utf8-query/get-vanilla-utf8-query.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | %E1%88%B4=bar 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative-relative/get-relative-relative.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-after/post-sts-header-after.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-value-order/get-header-value-order.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=08c7e5a9acfcfeb3ab6b2185e75ce8b1deb5e634ec47601a50643f830c755c01 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=a67d582fa61cc504c4bae71f336f98b97f1ea3c7a6bfe1b6e45aec72011b9aeb -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | Param1=value1 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.creq: -------------------------------------------------------------------------------- 1 | GET 2 | /example 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-sort/post-header-key-sort.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c5410059b04c1ee005303aed430f6e6645f61f4dc9e1461ec8f8916fdf18852c -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-value-case/post-header-value-case.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=cdbc9802e29d2942e5e10b5bccfdd67c5f22c7c4e8ae67b53629efa58b974b7d -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Content-Type:application/x-www-form-urlencoded; charset=utf8 3 | Host:example.amazonaws.com 4 | X-Amz-Date:20150830T123600Z 5 | 6 | Param1=value1 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-key-duplicate/get-header-key-duplicate.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c9d5ea9f3f72853aea855b47ea873832890dbdd183b4468f858259531a5138ea -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9c3e54bfcdf0b19771a7f523ee5669cdf59bc7cc0884027167c21bb143a40197 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative-relative/get-relative-relative.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-sort/post-header-key-sort.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | host:example.amazonaws.com 5 | my-header1:value1 6 | x-amz-date:20150830T123600Z 7 | 8 | host;my-header1;x-amz-date 9 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-after/post-sts-header-after.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5da7c1a2acd57cee7505fc6676e4e544621c30862966e37dddb68e92efbe5d6b -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=28038455d6de14eafc1f9222cf5aa6f1a96197d7deb8263271d420d138af7f11 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | Param1=value1 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | [*.lua] 8 | indent_style = space 9 | indent_size = 4 10 | 11 | [*.t] 12 | indent_style = space 13 | indent_size = 4 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=b97d918cfa904a5beff61c982a1b6f458b799221646efd99d3219ec94cdf2500 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=ef75d96142cf21edca26f06005da7988e4f8dc83a165a80865db7089db637ec5 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-value-case/post-header-value-case.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | host:example.amazonaws.com 5 | my-header1:VALUE1 6 | x-amz-date:20150830T123600Z 7 | 8 | host;my-header1;x-amz-date 9 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=ff11897932ad3f4e8b18135d722051e5ac45fc38421b1da7b9d196a0fe09473a -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | Param1=value1&Param2=value2 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-key-duplicate/get-header-key-duplicate.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | my-header1:value2,value2,value1 6 | x-amz-date:20150830T123600Z 7 | 8 | host;my-header1;x-amz-date 9 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-unreserved/get-unreserved.creq: -------------------------------------------------------------------------------- 1 | GET 2 | /-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.req: -------------------------------------------------------------------------------- 1 | GET /?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-before/post-sts-header-before.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=85d96828115b5dc0cfc3bd16ad9e210dd772bbebba041836c64533a82be05ead -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-value-order/get-header-value-order.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | 4 | host:example.amazonaws.com 5 | my-header1:value4,value1,value3,value2 6 | x-amz-date:20150830T123600Z 7 | 8 | host;my-header1;x-amz-date 9 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.authz: -------------------------------------------------------------------------------- 1 | AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=1a72ec8f64bd914b0e42e42607c7fbce7fb2c7465f63e3092b3b0d39fa77a6fe -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | content-type:application/x-www-form-urlencoded 5 | host:example.amazonaws.com 6 | x-amz-date:20150830T123600Z 7 | 8 | content-type;host;x-amz-date 9 | 9095672bbd1f56dfc5b65f3e153adc8731a4a654192329106275f4c7b24d0b6e -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla/get-vanilla.sreq: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla/post-vanilla.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5da7c1a2acd57cee7505fc6676e4e544621c30862966e37dddb68e92efbe5d6b -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query/get-vanilla-query.sreq: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash/get-slash.sreq: -------------------------------------------------------------------------------- 1 | GET // HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-case/post-header-key-case.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5da7c1a2acd57cee7505fc6676e4e544621c30862966e37dddb68e92efbe5d6b -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | content-type:application/x-www-form-urlencoded; charset=utf8 5 | host:example.amazonaws.com 6 | x-amz-date:20150830T123600Z 7 | 8 | content-type;host;x-amz-date 9 | 9095672bbd1f56dfc5b65f3e153adc8731a4a654192329106275f4c7b24d0b6e -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative/get-relative.sreq: -------------------------------------------------------------------------------- 1 | GET /example/.. HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slashes/get-slashes.sreq: -------------------------------------------------------------------------------- 1 | GET //example// HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9a624bd73a37c9a373b5312afbebe7a714a789de108f0bdfe846570885f57e84 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-space/get-space.sreq: -------------------------------------------------------------------------------- 1 | GET /example space/ HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=652487583200325589f1fba4c7e578f72c47cb61beeca81406b39ddec1366741 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-utf8-query/get-vanilla-utf8-query.sreq: -------------------------------------------------------------------------------- 1 | GET /?ሴ=bar HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=2cdec8eed098649ff3a119c94853b13c643bcf08f8b0a1d91e12c9027818dd04 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-query/post-vanilla-query.sreq: -------------------------------------------------------------------------------- 1 | POST /?Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=28038455d6de14eafc1f9222cf5aa6f1a96197d7deb8263271d420d138af7f11 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-dot-slash/get-slash-dot-slash.sreq: -------------------------------------------------------------------------------- 1 | GET /./ HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-empty-query-key/get-vanilla-empty-query-key.sreq: -------------------------------------------------------------------------------- 1 | GET /?Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=a67d582fa61cc504c4bae71f336f98b97f1ea3c7a6bfe1b6e45aec72011b9aeb -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-slash-pointless-dot/get-slash-pointless-dot.sreq: -------------------------------------------------------------------------------- 1 | GET /./example HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=ef75d96142cf21edca26f06005da7988e4f8dc83a165a80865db7089db637ec5 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-key-sort/post-header-key-sort.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:value1 4 | X-Amz-Date:20150830T123600Z 5 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c5410059b04c1ee005303aed430f6e6645f61f4dc9e1461ec8f8916fdf18852c -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.creq: -------------------------------------------------------------------------------- 1 | GET 2 | / 3 | -._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | 7 | host;x-amz-date 8 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-header-value-case/post-header-value-case.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:VALUE1 4 | X-Amz-Date:20150830T123600Z 5 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=cdbc9802e29d2942e5e10b5bccfdd67c5f22c7c4e8ae67b53629efa58b974b7d -------------------------------------------------------------------------------- /test/aws4_testsuite/post-vanilla-empty-query-value/post-vanilla-empty-query-value.sreq: -------------------------------------------------------------------------------- 1 | POST /?Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=28038455d6de14eafc1f9222cf5aa6f1a96197d7deb8263271d420d138af7f11 -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/get-relative-relative/get-relative-relative.sreq: -------------------------------------------------------------------------------- 1 | GET /example1/example2/../.. HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-unreserved/get-unreserved.sreq: -------------------------------------------------------------------------------- 1 | GET /-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=07ef7494c76fa4850883e2b006601f940f8a34d404d0cfa977f52a65bbf5f24f -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-order-key-case/get-vanilla-query-order-key-case.sreq: -------------------------------------------------------------------------------- 1 | GET /?Param2=value2&Param1=value1 HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=b97d918cfa904a5beff61c982a1b6f458b799221646efd99d3219ec94cdf2500 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-key-duplicate/get-header-key-duplicate.sreq: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:value2 4 | My-Header1:value2 5 | My-Header1:value1 6 | X-Amz-Date:20150830T123600Z 7 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c9d5ea9f3f72853aea855b47ea873832890dbdd183b4468f858259531a5138ea -------------------------------------------------------------------------------- /test/aws4_testsuite/get-header-value-order/get-header-value-order.sreq: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host:example.amazonaws.com 3 | My-Header1:value4 4 | My-Header1:value1 5 | My-Header1:value3 6 | My-Header1:value2 7 | X-Amz-Date:20150830T123600Z 8 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=08c7e5a9acfcfeb3ab6b2185e75ce8b1deb5e634ec47601a50643f830c755c01 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded/post-x-www-form-urlencoded.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Content-Type:application/x-www-form-urlencoded 3 | Host:example.amazonaws.com 4 | X-Amz-Date:20150830T123600Z 5 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=ff11897932ad3f4e8b18135d722051e5ac45fc38421b1da7b9d196a0fe09473a 6 | 7 | Param1=value1 -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: clean src codegen 3 | cp codegen/dist/*.lua lib/resty/aws/ 4 | 5 | .PHONY: build 6 | 7 | src: 8 | cp src/*.lua lib/resty/aws/ 9 | 10 | .PHONY: src 11 | 12 | codegen: 13 | make -C codegen 14 | 15 | .PHONY: codegen 16 | 17 | test: 18 | /usr/local/openresty/bin/resty ./scripts/busted test 19 | 20 | .PHONY: test 21 | 22 | clean: 23 | -make -C codegen clean 24 | -rm lib/resty/aws/*.lua 25 | 26 | .PHONY: clean 27 | -------------------------------------------------------------------------------- /codegen/Makefile: -------------------------------------------------------------------------------- 1 | RESTY="/usr/local/openresty/bin/resty" 2 | 3 | build: clean dist/lambda.lua dist/sns.lua dist/sqs.lua 4 | 5 | .PHONY: build 6 | 7 | dist: 8 | mkdir -p dist 9 | 10 | dist/lambda.lua: dist 11 | RESTY ./main.lua lambda > dist/lambda.lua 12 | 13 | dist/sns.lua: dist 14 | RESTY ./main.lua sns > dist/sns.lua 15 | 16 | dist/sqs.lua: dist 17 | RESTY ./main.lua sqs > dist/sqs.lua 18 | 19 | clean: 20 | -rm -rf dist 21 | 22 | .PHONY: clean 23 | 24 | -------------------------------------------------------------------------------- /test/aws4_testsuite/post-x-www-form-urlencoded-parameters/post-x-www-form-urlencoded-parameters.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Content-Type:application/x-www-form-urlencoded; charset=utf8 3 | Host:example.amazonaws.com 4 | X-Amz-Date:20150830T123600Z 5 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=1a72ec8f64bd914b0e42e42607c7fbce7fb2c7465f63e3092b3b0d39fa77a6fe 6 | 7 | Param1=value1 -------------------------------------------------------------------------------- /test/aws4_testsuite/get-vanilla-query-unreserved/get-vanilla-query-unreserved.sreq: -------------------------------------------------------------------------------- 1 | GET /?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9c3e54bfcdf0b19771a7f523ee5669cdf59bc7cc0884027167c21bb143a40197 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-before/post-sts-header-before.req: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | X-Amz-Security-Token:AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGdQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== -------------------------------------------------------------------------------- /test/aws4_testsuite/normalize-path/normalize-path.txt: -------------------------------------------------------------------------------- 1 | A note about signing requests to Amazon S3: 2 | 3 | In exception to this, you do not normalize URI paths for requests to Amazon S3. For example, if you have a bucket with an object named my-object//example//photo.user, use that path. Normalizing the path to my-object/example/photo.user will cause the request to fail. For more information, see Task 1: Create a Canonical Request in the Amazon Simple Storage Service API Reference: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html#canonical-request -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-before/post-sts-header-before.creq: -------------------------------------------------------------------------------- 1 | POST 2 | / 3 | 4 | host:example.amazonaws.com 5 | x-amz-date:20150830T123600Z 6 | x-amz-security-token:AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGdQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== 7 | 8 | host;x-amz-date;x-amz-security-token 9 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-after/post-sts-header-after.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | X-Amz-Security-Token:AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGdQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== 5 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5da7c1a2acd57cee7505fc6676e4e544621c30862966e37dddb68e92efbe5d6b -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/post-sts-header-before/post-sts-header-before.sreq: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host:example.amazonaws.com 3 | X-Amz-Date:20150830T123600Z 4 | X-Amz-Security-Token:AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGdQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== 5 | Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=85d96828115b5dc0cfc3bd16ad9e210dd772bbebba041836c64533a82be05ead -------------------------------------------------------------------------------- /lua-resty-aws-sdk-0.1-0.rockspec: -------------------------------------------------------------------------------- 1 | package = "lua-resty-aws-sdk" 2 | version = "0.1-0" 3 | source = { 4 | url = "git://github.com/kiddkai/lua-resty-aws-sdk", 5 | tag = "v0.1.0" 6 | } 7 | description = { 8 | summary = "A generic long running task daemon", 9 | homepage = "https://github.com/kiddkai/lua-resty-aws-sdk", 10 | license = "2-clause BSD", 11 | maintainer = "Zekai Zheng(kiddkai@gmail.com)" 12 | } 13 | dependencies = { 14 | "lua >= 5.1", 15 | "lua-resty-http ~> 0.10-0" 16 | } 17 | build = { 18 | type = "builtin", 19 | modules = { 20 | ["resty.aws.request"] = "lib/resty/aws/request", 21 | ["resty.aws.signature"] = "lib/resty/aws/signature", 22 | ["resty.aws.cred"] = "lib/resty/aws/cred", 23 | ["resty.aws.sns"] = "lib/resty/aws/sns", 24 | ["resty.aws.sqs"] = "lib/resty/aws/sqs", 25 | ["resty.aws.lambda"] = "lib/resty/aws/lambda.lua" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /codegen/tpl.lua: -------------------------------------------------------------------------------- 1 | -- 2 | --- @module resty.aws.$(NAME) 3 | 4 | local _M = {} 5 | local http = require 'resty.http' 6 | local request = require 'resty.aws.request' 7 | 8 | local VERSION = '$(API_VERSION)' 9 | local CONTENT_TYPE = '$(CONTENT_TYPE)' 10 | local SIGNATURE_VERSION = '$(SIGNATURE_VERSION)' 11 | 12 | local REGIONS = { 13 | # for _, region in pairs(REGIONS) do 14 | ['$(region)'] = '$(region)', 15 | # end 16 | } 17 | 18 | local ENDPOINTS = { 19 | # for _, e in ipairs(ENDPOINTS) do 20 | ['$(e[1])'] = '$(e[2])', 21 | # end 22 | } 23 | 24 | local mt = { __index = _M } 25 | 26 | function _M.new(_, region) 27 | local r = string.lower(region or os.getenv('AWS_DEFAULT_REGION')) 28 | 29 | if not r then 30 | return nil, '[$(NAME)] region[' .. region .. '] is not available for this service' 31 | end 32 | 33 | return setmetatable({ 34 | service = '$(NAME)', 35 | scope = r .. '/$(NAME)/aws4_request', 36 | host = ENDPOINTS[r] 37 | }, mt) 38 | end 39 | 40 | 41 | $(METHODS) 42 | 43 | 44 | return _M 45 | 46 | -------------------------------------------------------------------------------- /examples/lambda_no_body.lua: -------------------------------------------------------------------------------- 1 | local lambda = require 'resty.aws.lambda' 2 | local cred = require 'resty.aws.cred' 3 | local json = require 'cjson' 4 | local pp = require 'pl.pretty' 5 | local http = require 'resty.http' 6 | 7 | local c = cred.from_env() 8 | local l = lambda:new("ap-southeast-2") 9 | --local body = json.encode({ 10 | -- foo = 'bar' 11 | --}) 12 | local body = '' 13 | 14 | -- e30= is {} base64 encoded 15 | local req = l:Invoke(c, { 16 | ['FunctionName'] = 'bs', 17 | ['X-Amz-Client-Context'] = 'e30=' 18 | }, body) 19 | 20 | pp.dump(req) 21 | 22 | local headers = {} 23 | for _, h in pairs(req.headers) do 24 | headers[h[1]] = h[2] 25 | end 26 | local httpc = http.new() 27 | httpc:set_timeout(500) 28 | httpc:connect(req.hostname, req.port) 29 | local sess, err = httpc:ssl_handshake() 30 | local res, err = httpc:request({ 31 | path = req.pathname .. req.query, 32 | method = req.method, 33 | body = '', 34 | headers = headers 35 | }) 36 | if not res then 37 | print(err) 38 | return 39 | end 40 | local json = require 'cjson' 41 | print(res:read_body()) 42 | -------------------------------------------------------------------------------- /codegen/method_tpl.lua: -------------------------------------------------------------------------------- 1 | # if #QUERIES > 0 then 2 | local $(NAME:upper())_QUERY_KEYS = { $(table.concat(QUERIES, ', ')) } 3 | # end 4 | # if #HEADERS > 0 then 5 | local $(NAME:upper())_HEADER_KEYS = { $(table.concat(HEADERS, ', ')) } 6 | # end 7 | function _M.$(NAME)(self, $(ARGS), data) 8 | # for _, URI_SEG in pairs(URI_PARAMS) do 9 | local $(URI_SEG) = opts['$(URI_SEG)'] 10 | if not $(URI_SEG) then 11 | return nil, '$(URI_SEG) is required' 12 | end 13 | 14 | # end 15 | return request({ 16 | signature_version = SIGNATURE_VERSION, 17 | version = VERSION, 18 | service = self.service, 19 | host = self.host, 20 | scope = self.scope, 21 | action = '$(NAME)', 22 | method = '$(METHOD)', 23 | cred = cred, 24 | content_type = CONTENT_TYPE, 25 | pathname = $(URI), 26 | body = data or '', 27 | # if #QUERIES > 0 then 28 | query_keys = $(NAME:upper())_QUERY_KEYS, 29 | query_data = opts, 30 | # end 31 | # if #HEADERS > 0 then 32 | header_keys = $(NAME:upper())_HEADER_KEYS, 33 | header_data = opts, 34 | # end 35 | }) 36 | end 37 | -------------------------------------------------------------------------------- /src/cred.lua: -------------------------------------------------------------------------------- 1 | local http = require 'resty.http' 2 | local json = require 'cjson' 3 | local _M = {} 4 | 5 | function _M.from_env() 6 | local key_id = os.getenv('AWS_ACCESS_KEY_ID') 7 | local secret = os.getenv('AWS_SECRET_ACCESS_KEY') 8 | local session_token = os.getenv('AWS_SESSION_TOKEN') 9 | 10 | if not key_id or not secret then 11 | return nil, 'not found' 12 | end 13 | 14 | return { 15 | key = key_id, 16 | secret = secret, 17 | session_token = session_token 18 | } 19 | end 20 | 21 | 22 | 23 | function _M.from_iam_role(role_name, host) 24 | host = host or '169.254.169.254' 25 | local httpc = http.new() 26 | local res, err = httpc:request_uri('http://' .. host .. '/latest/meta-data/iam/security-credentials/' .. role_name) 27 | 28 | if not res then 29 | return nil, err 30 | end 31 | 32 | if res.status == 404 then 33 | return nil, 'iam role not found' 34 | end 35 | 36 | if res.status ~= 200 then 37 | return nil, res.body 38 | end 39 | 40 | local body = json.decode(res.body) 41 | 42 | return { 43 | key = body['AccessKeyId'], 44 | secret = body['SecretAccessKey'], 45 | session_token = body['Token'] 46 | } 47 | end 48 | 49 | 50 | 51 | return _M 52 | 53 | -------------------------------------------------------------------------------- /lib/resty/aws/cred.lua: -------------------------------------------------------------------------------- 1 | local http = require 'resty.http' 2 | local json = require 'cjson' 3 | local _M = {} 4 | 5 | function _M.from_env() 6 | local key_id = os.getenv('AWS_ACCESS_KEY_ID') 7 | local secret = os.getenv('AWS_SECRET_ACCESS_KEY') 8 | local session_token = os.getenv('AWS_SESSION_TOKEN') 9 | 10 | if not key_id or not secret then 11 | return nil, 'not found' 12 | end 13 | 14 | return { 15 | key = key_id, 16 | secret = secret, 17 | session_token = session_token 18 | } 19 | end 20 | 21 | 22 | 23 | function _M.from_iam_role(role_name, host) 24 | host = host or '169.254.169.254' 25 | local httpc = http.new() 26 | local res, err = httpc:request_uri('http://' .. host .. '/latest/meta-data/iam/security-credentials/' .. role_name) 27 | 28 | if not res then 29 | return nil, err 30 | end 31 | 32 | if res.status == 404 then 33 | return nil, 'iam role not found' 34 | end 35 | 36 | if res.status ~= 200 then 37 | return nil, res.body 38 | end 39 | 40 | local body = json.decode(res.body) 41 | 42 | return { 43 | key = body['AccessKeyId'], 44 | secret = body['SecretAccessKey'], 45 | session_token = body['Token'] 46 | } 47 | end 48 | 49 | 50 | 51 | return _M 52 | 53 | -------------------------------------------------------------------------------- /test/aws4_testsuite/post-sts-token/readme.txt: -------------------------------------------------------------------------------- 1 | A note about using temporary security credentials: 2 | 3 | You can use temporary security credentials provided by the AWS Security Token Service (AWS STS) to sign a request. The process is the same as using long-term credentials but requires an additional HTTP header or query string parameter for the security token. The name of the header or query string parameter is X-Amz-Security-Token, and the value is the session token (the string that you received from AWS STS when you obtained temporary security credentials). 4 | 5 | When you add X-Amz-Security-Token, some services require that you include this parameter in the canonical (signed) request. For other services, you add this parameter at the end, after you calculate the signature. For details see the API reference documentation for that service. 6 | 7 | The test suite has 2 examples: 8 | 9 | post-sts-header-before - The X-Amz-Security-Token header is part of the canonical request. 10 | 11 | post-sts-header-after - The X-Amz-Security-Token header is added to the request after you calculate the signature. 12 | 13 | The test suite uses this example value for X-Amz-Security-Token: 14 | 15 | AQoDYXdzEPT//////////wEXAMPLEtc764bNrC9SAPBSM22wDOk4x4HIZ8j4FZTwdQWLWsKWHGBuFqwAeMicRXmxfpSPfIeoIYRqTflfKD8YUuwthAx7mSEI/qkPpKPi/kMcGdQrmGdeehM4IC1NtBmUpp2wUE8phUZampKsburEDy0KPkyQDYwT7WZ0wq5VSXDvp75YU9HFvlRd8Tx6q6fE8YQcHNVXAkiY9q6d+xo0rKwT38xVqr7ZD0u0iPPkUL64lIZbqBAz+scqKmlzm8FDrypNC9Yjc8fPOLn9FX9KSYvKTr4rvx3iSIlTJabIQwj2ICCR/oLxBA== -------------------------------------------------------------------------------- /src/request.lua: -------------------------------------------------------------------------------- 1 | local ngx = require 'ngx' 2 | local signature = require 'resty.aws.signature' 3 | 4 | 5 | local function build_query(opts) 6 | local queries = {} 7 | local keys = opts.query_keys 8 | local data = opts.query_data 9 | local key 10 | 11 | if keys then 12 | for i = 1, #keys do 13 | key = keys[i] 14 | if data[key] then 15 | table.insert(queries, { key, data[key] }) 16 | end 17 | end 18 | end 19 | 20 | return queries 21 | end 22 | 23 | 24 | 25 | local function build_v4_headers(opts, queries) 26 | local content_type = opts.content_type 27 | local accept = content_type 28 | local method = opts.method 29 | local pathname = opts.pathname 30 | local cred = opts.cred 31 | local header_keys = opts.header_keys 32 | local header_data = opts.header_data 33 | local datetime = signature.amz_date() 34 | local date = string.sub(datetime, 1, 8) 35 | local headers = {} 36 | 37 | if header_keys then 38 | for i = 1, #header_keys do 39 | local k = header_keys[i] 40 | local low_k = string.lower(k) 41 | if low_k == 'x-amz-date' then 42 | table.insert(headers, { k, datetime }) 43 | elseif low_k == 'host' then 44 | table.insert(headers, { k, opts.host }) 45 | elseif low_k == 'x-amz-security-token' then 46 | if cred.session_token then 47 | table.insert(headers, { k, cred.session_token }) 48 | end 49 | elseif header_data[k] then 50 | table.insert(headers, { k, header_data[k] }) 51 | end 52 | end 53 | end 54 | 55 | 56 | local canonical_str, signed_headers = signature.new_canonical_request( 57 | method, 58 | pathname, 59 | queries, 60 | headers, 61 | opts.body 62 | ) 63 | 64 | local canonical_hash = signature.hash(canonical_str) 65 | local str_to_sign = signature.str_to_sign(canonical_hash, headers, opts.region, opts.service) 66 | local auth_header = signature.new_auth_header(cred, signed_headers, date, opts.region, opts.service, str_to_sign) 67 | 68 | table.insert(headers, { 'content-type', content_type }) 69 | table.insert(headers, { 'accept', accept }) 70 | table.insert(headers, { 'Authorization' , auth_header }) 71 | 72 | return headers 73 | end 74 | 75 | 76 | local function build_headers(opts, queries) 77 | local signature_version = opts.signature_version 78 | 79 | if string.find(signature_version, 'v4') then 80 | return build_v4_headers(opts, queries) 81 | elseif string.find(signature_version, 's3') then 82 | error('not supporting s3 signature yet') 83 | end 84 | end 85 | 86 | 87 | local function query_to_str(queries) 88 | local len = #queries 89 | 90 | if len == 0 then 91 | return '' 92 | end 93 | 94 | local res = '?' 95 | local item 96 | for i = 1, len do 97 | item = queries[i] 98 | res = res .. tostring(item[1]) .. '=' .. ngx.escape_uri(item[2]) 99 | 100 | if i < len then 101 | res = res .. '&' 102 | end 103 | end 104 | return res 105 | end 106 | 107 | 108 | local function request(opts) 109 | local queries = build_query(opts) 110 | local headers = build_headers(opts, queries) 111 | 112 | return { 113 | headers = headers, 114 | hostname = opts.host, 115 | port = 443, 116 | pathname = opts.pathname, 117 | method = opts.method, 118 | query = query_to_str(queries), 119 | body = opts.body 120 | } 121 | end 122 | 123 | 124 | 125 | return request 126 | 127 | -------------------------------------------------------------------------------- /lib/resty/aws/request.lua: -------------------------------------------------------------------------------- 1 | local ngx = require 'ngx' 2 | local signature = require 'resty.aws.signature' 3 | 4 | 5 | local function build_query(opts) 6 | local queries = {} 7 | local keys = opts.query_keys 8 | local data = opts.query_data 9 | local key 10 | 11 | if keys then 12 | for i = 1, #keys do 13 | key = keys[i] 14 | if data[key] then 15 | table.insert(queries, { key, data[key] }) 16 | end 17 | end 18 | end 19 | 20 | return queries 21 | end 22 | 23 | 24 | 25 | local function build_v4_headers(opts, queries) 26 | local content_type = opts.content_type 27 | local accept = content_type 28 | local method = opts.method 29 | local pathname = opts.pathname 30 | local cred = opts.cred 31 | local header_keys = opts.header_keys 32 | local header_data = opts.header_data 33 | local datetime = signature.amz_date() 34 | local date = string.sub(datetime, 1, 8) 35 | local headers = {} 36 | 37 | if header_keys then 38 | for i = 1, #header_keys do 39 | local k = header_keys[i] 40 | local low_k = string.lower(k) 41 | if low_k == 'x-amz-date' then 42 | table.insert(headers, { k, datetime }) 43 | elseif low_k == 'host' then 44 | table.insert(headers, { k, opts.host }) 45 | elseif low_k == 'x-amz-security-token' then 46 | if cred.session_token then 47 | table.insert(headers, { k, cred.session_token }) 48 | end 49 | elseif header_data[k] then 50 | table.insert(headers, { k, header_data[k] }) 51 | end 52 | end 53 | end 54 | 55 | 56 | local canonical_str, signed_headers = signature.new_canonical_request( 57 | method, 58 | pathname, 59 | queries, 60 | headers, 61 | opts.body 62 | ) 63 | 64 | local canonical_hash = signature.hash(canonical_str) 65 | local str_to_sign = signature.str_to_sign(canonical_hash, headers, opts.region, opts.service) 66 | local auth_header = signature.new_auth_header(cred, signed_headers, date, opts.region, opts.service, str_to_sign) 67 | 68 | table.insert(headers, { 'content-type', content_type }) 69 | table.insert(headers, { 'accept', accept }) 70 | table.insert(headers, { 'Authorization' , auth_header }) 71 | 72 | return headers 73 | end 74 | 75 | 76 | local function build_headers(opts, queries) 77 | local signature_version = opts.signature_version 78 | 79 | if string.find(signature_version, 'v4') then 80 | return build_v4_headers(opts, queries) 81 | elseif string.find(signature_version, 's3') then 82 | error('not supporting s3 signature yet') 83 | end 84 | end 85 | 86 | 87 | local function query_to_str(queries) 88 | local len = #queries 89 | 90 | if len == 0 then 91 | return '' 92 | end 93 | 94 | local res = '?' 95 | local item 96 | for i = 1, len do 97 | item = queries[i] 98 | res = res .. tostring(item[1]) .. '=' .. ngx.escape_uri(item[2]) 99 | 100 | if i < len then 101 | res = res .. '&' 102 | end 103 | end 104 | return res 105 | end 106 | 107 | 108 | local function request(opts) 109 | local queries = build_query(opts) 110 | local headers = build_headers(opts, queries) 111 | 112 | return { 113 | headers = headers, 114 | hostname = opts.host, 115 | port = 443, 116 | pathname = opts.pathname, 117 | method = opts.method, 118 | query = query_to_str(queries), 119 | body = opts.body 120 | } 121 | end 122 | 123 | 124 | 125 | return request 126 | 127 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Name 2 | 3 | lua-resty-aws-sdk - a raw aws sdk generated from API specification 4 | 5 | ## Table of Contents 6 | 7 | * [Name](#Name) 8 | * [Status](#Status) 9 | 10 | ## Status 11 | 12 | This library is not ready for production. 13 | 14 | ## Description 15 | 16 | This Lua library provides basic aws request signing and creating feature. You can use this module 17 | with `proxy_pass`, or `lua-resty-http` or any other library you want. 18 | 19 | ## Synopsis 20 | 21 | ```lua 22 | local lambda = require 'resty.aws.lambda' 23 | local cred = require 'resty.aws.cred' 24 | local json = require 'cjson' 25 | 26 | local c = cred.from_env() 27 | local l = lambda:new() 28 | local body = json.encode({ 29 | foo = 'bar' 30 | }) 31 | 32 | local req = l:Invoke(c, { 33 | FunctionName = 'test', 34 | ['X-Amz-Client-Context'] = '' 35 | }, body) 36 | 37 | -- do something with req 38 | ``` 39 | 40 | ## Request Structure 41 | 42 | The `req` variable in the code above is just a data object which includes the following informations: 43 | 44 | * headers - headers as a `{ { k, v } }` list 45 | * hostname - the hostname which you can send the api request to 46 | * port - the port, 443 only 47 | * pathname - the pathname for the api 48 | * method - the request method you can use to send the api request 49 | * query - the query string as string 50 | * body - the request body 51 | 52 | Because the aws sdk api only provides you data. You can build your own APIs on top of them. It doesn't 53 | care about which `http` library you use. 54 | 55 | ## Credentials 56 | 57 | AWS credentials is a very important in the API request. So make sure you choose the right way to read 58 | and pass your credential to the request. 59 | 60 | In this library. It provides a module called `resty.aws.cred`. Which allows you get your credential from 61 | different places. 62 | 63 | The credential table will have a data structure which looks like this: 64 | 65 | ``` 66 | { 67 | key = String, 68 | secret = String, 69 | session_token = ?String 70 | } 71 | ``` 72 | 73 | The session token is widly used in different places `iam/sts`. But is not a required field. 74 | 75 | ### `from_env` 76 | 77 | This function will help you create a new credential table using `AWS_` related environment variables, the name 78 | of the variables are consist with `aws-cli`. 79 | 80 | - AWS_ACCESS_KEY_ID 81 | - AWS_SECRET_ACCESS_KEY 82 | - AWS_SESSION_TOKEN 83 | 84 | ```lua 85 | local c = require 'resty.aws.cred' 86 | local credential = c.from_env() 87 | ``` 88 | 89 | ### `from_iam` 90 | 91 | This function will help you create a new credential table using `iam` role which your related to the resource(ec2/ecs/..) 92 | you use. It simply sends http request to `169.254.169.254` to get the metadata informations. For more information about 93 | `iam` role and metadata. You need to check the [AWS Document](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) 94 | about it. 95 | 96 | 97 | ```lua 98 | local c = require 'resty.aws.cred' 99 | local credential = c.from_iam('lambdainvoke') 100 | ``` 101 | 102 | 103 | ## Contribute 104 | 105 | Service source files are generated using the `codegen/main.lua` file to create. All service file share the same format. And 106 | `botocore` as a submodule provides a nice API specification. We don't need to do the busywork to create lua api for every 107 | service manually. Instead, once we finish the code generation script. The `api-spec` + `codegen` will generate the code for 108 | us. So, don't change the code manually in the `lib/resty/aws` directory. 109 | 110 | ## Support signature methods 111 | 112 | - [v4](http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html) 113 | 114 | ## Implemented Services 115 | 116 | - `resty.aws.lambda` 117 | - `resty.aws.sqs` 118 | - `resty.aws.sns` 119 | 120 | ## Todo 121 | 122 | - `resty.aws.s3` 123 | - `resty.aws.cloudwatch` 124 | - `resty.aws.elb` 125 | - `resty.aws.kinesis` 126 | - `resty.aws.logs` 127 | - `resty.aws.kms` 128 | - `resty.aws.cognito-identity` 129 | 130 | 131 | ## Not Yet Implemented 132 | 133 | - [s3 signigure](http://docs.aws.amazon.com/AmazonS3/latest/API/bucket-policy-s3-sigv4-conditions.html) 134 | 135 | -------------------------------------------------------------------------------- /src/signature.lua: -------------------------------------------------------------------------------- 1 | local ngx = require 'ngx' 2 | local sha256 = require 'resty.sha256' 3 | local str = require 'resty.string' 4 | local ffi = require "ffi" 5 | local ffi_new = ffi.new 6 | local ffi_str = ffi.string 7 | local C = ffi.C 8 | 9 | local ok, new_tab = pcall(require, "table.new") 10 | if not ok then 11 | new_tab = function (narr, nrec) return {} end 12 | end 13 | 14 | local _M = {} 15 | 16 | ffi.cdef [[ 17 | typedef struct env_md_st EVP_MD; 18 | typedef struct env_md_ctx_st EVP_MD_CTX; 19 | unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, 20 | const unsigned char *d, size_t n, unsigned char *md, 21 | unsigned int *md_len); 22 | const EVP_MD *EVP_sha256(void); 23 | ]] 24 | 25 | 26 | 27 | local digest_len = ffi_new("int[?]", 64) 28 | local buf = ffi_new("char[?]", 64) 29 | 30 | 31 | 32 | local function hmac_sha256(key, msg) 33 | C.HMAC(C.EVP_sha256(), key, #key, msg, #msg, buf, digest_len) 34 | return ffi_str(buf, 32) 35 | end 36 | 37 | 38 | _M.hmac_sha256 = hmac_sha256 39 | 40 | 41 | 42 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 43 | local function sha256_hex(payload) 44 | local hasher = sha256:new() 45 | hasher:update(payload) 46 | local hashed = hasher:final() 47 | return str.to_hex(hashed) 48 | end 49 | 50 | 51 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 52 | local function encode_headers(headers) 53 | local header, vidx 54 | local visited = {} 55 | local result = {} 56 | local sign_headers = {} 57 | for i = 1, #headers do 58 | header = headers[i] 59 | local header_name = string.lower(header[1]) 60 | vidx = visited[header_name] 61 | if not vidx then 62 | table.insert(result, header_name .. ':' .. header[2]) 63 | table.insert(sign_headers, header_name) 64 | visited[header_name] = #result 65 | else 66 | result[vidx] = result[vidx] .. ',' .. header[2] 67 | end 68 | end 69 | return table.concat(result, '\n') .. '\n', table.concat(sign_headers, ';') 70 | end 71 | 72 | 73 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 74 | local function encode_args(to_encode) 75 | local args = new_tab(#to_encode, 0) 76 | local arg 77 | local val 78 | for i = 1, #to_encode do 79 | arg = to_encode[i] 80 | val = ngx.escape_uri(arg[2] or '') 81 | -- escape_uri does not handling '$' correctly 82 | val = ngx.re.gsub(val, '\\$', '%24') 83 | args[i] = ngx.escape_uri(arg[1]) .. '=' .. val 84 | end 85 | return table.concat(args, '&') 86 | end 87 | 88 | 89 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 90 | local function canonical_req(method, uri, query, headers, payload) 91 | local encoded_headers, sign_headers = encode_headers(headers) 92 | local cstr = string.upper(method) .. '\n' .. 93 | uri .. '\n' .. 94 | encode_args(query) .. '\n' .. 95 | encoded_headers .. '\n' .. 96 | sign_headers .. '\n' .. 97 | sha256_hex(payload) 98 | 99 | return cstr, sign_headers 100 | end 101 | 102 | 103 | 104 | _M.new_canonical_request = canonical_req 105 | _M.hash = sha256_hex 106 | 107 | 108 | 109 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 110 | local function amz_date() 111 | local date = ngx.re.gsub(ngx.utctime(), '(-|:)', '') 112 | 113 | return string.format('%sT%sZ', 114 | string.sub(date, 1, 8), 115 | string.sub(date, 10, string.len(date))) 116 | end 117 | 118 | 119 | 120 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 121 | local function date() 122 | local d = ngx.re.gsub(ngx.utctime(), '-', '') 123 | return string.sub(d, 1, 8) 124 | end 125 | 126 | 127 | 128 | _M.amz_date = amz_date 129 | _M.date = date 130 | 131 | 132 | 133 | local function str_to_sign(canonical_hash, headers, region, service) 134 | local amz_d 135 | 136 | for i = 1, #headers do 137 | if string.lower(headers[i][1]) == 'x-amz-date' then 138 | amz_d = headers[i][2] 139 | end 140 | end 141 | 142 | if not amz_d then 143 | amz_d = amz_date() 144 | table.insert(headers, { 'x-amz-date', amz_d }) 145 | end 146 | 147 | return 'AWS4-HMAC-SHA256\n' .. 148 | amz_d .. '\n' .. 149 | string.sub(amz_d, 1, 8) .. '/' .. region .. '/' .. service .. '/aws4_request\n' .. 150 | canonical_hash 151 | end 152 | 153 | 154 | 155 | _M.str_to_sign = str_to_sign 156 | 157 | 158 | 159 | local function derive_key(aws_secret, d, region, service) 160 | local ord = { region, service, 'aws4_request' } 161 | local len = #ord 162 | local k 163 | 164 | k = hmac_sha256('AWS4' .. aws_secret, d) 165 | 166 | for i=1, len do 167 | k = hmac_sha256(k, ord[i]) 168 | end 169 | 170 | return k 171 | end 172 | 173 | 174 | 175 | function _M.new_signature(aws_secret, d, region, service, data) 176 | return str.to_hex(hmac_sha256(derive_key(aws_secret, d, region, service), data)) 177 | end 178 | 179 | 180 | 181 | function _M.new_auth_header(cred, signed_headers, d, region, service, data) 182 | local signature = _M.new_signature(cred.secret, d, region, service, data) 183 | return 'AWS4-HMAC-SHA256 Credential=' .. cred.key .. '/' .. d .. '/' .. region .. '/' .. service .. '/aws4_request, SignedHeaders=' .. signed_headers .. ', Signature=' .. signature 184 | end 185 | 186 | 187 | 188 | return _M 189 | -------------------------------------------------------------------------------- /lib/resty/aws/signature.lua: -------------------------------------------------------------------------------- 1 | local ngx = require 'ngx' 2 | local sha256 = require 'resty.sha256' 3 | local str = require 'resty.string' 4 | local ffi = require "ffi" 5 | local ffi_new = ffi.new 6 | local ffi_str = ffi.string 7 | local C = ffi.C 8 | 9 | local ok, new_tab = pcall(require, "table.new") 10 | if not ok then 11 | new_tab = function (narr, nrec) return {} end 12 | end 13 | 14 | local _M = {} 15 | 16 | ffi.cdef [[ 17 | typedef struct env_md_st EVP_MD; 18 | typedef struct env_md_ctx_st EVP_MD_CTX; 19 | unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, 20 | const unsigned char *d, size_t n, unsigned char *md, 21 | unsigned int *md_len); 22 | const EVP_MD *EVP_sha256(void); 23 | ]] 24 | 25 | 26 | 27 | local digest_len = ffi_new("int[?]", 64) 28 | local buf = ffi_new("char[?]", 64) 29 | 30 | 31 | 32 | local function hmac_sha256(key, msg) 33 | C.HMAC(C.EVP_sha256(), key, #key, msg, #msg, buf, digest_len) 34 | return ffi_str(buf, 32) 35 | end 36 | 37 | 38 | _M.hmac_sha256 = hmac_sha256 39 | 40 | 41 | 42 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 43 | local function sha256_hex(payload) 44 | local hasher = sha256:new() 45 | hasher:update(payload) 46 | local hashed = hasher:final() 47 | return str.to_hex(hashed) 48 | end 49 | 50 | 51 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 52 | local function encode_headers(headers) 53 | local header, vidx 54 | local visited = {} 55 | local result = {} 56 | local sign_headers = {} 57 | for i = 1, #headers do 58 | header = headers[i] 59 | local header_name = string.lower(header[1]) 60 | vidx = visited[header_name] 61 | if not vidx then 62 | table.insert(result, header_name .. ':' .. header[2]) 63 | table.insert(sign_headers, header_name) 64 | visited[header_name] = #result 65 | else 66 | result[vidx] = result[vidx] .. ',' .. header[2] 67 | end 68 | end 69 | return table.concat(result, '\n') .. '\n', table.concat(sign_headers, ';') 70 | end 71 | 72 | 73 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 74 | local function encode_args(to_encode) 75 | local args = new_tab(#to_encode, 0) 76 | local arg 77 | local val 78 | for i = 1, #to_encode do 79 | arg = to_encode[i] 80 | val = ngx.escape_uri(arg[2] or '') 81 | -- escape_uri does not handling '$' correctly 82 | val = ngx.re.gsub(val, '\\$', '%24') 83 | args[i] = ngx.escape_uri(arg[1]) .. '=' .. val 84 | end 85 | return table.concat(args, '&') 86 | end 87 | 88 | 89 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 90 | local function canonical_req(method, uri, query, headers, payload) 91 | local encoded_headers, sign_headers = encode_headers(headers) 92 | local cstr = string.upper(method) .. '\n' .. 93 | uri .. '\n' .. 94 | encode_args(query) .. '\n' .. 95 | encoded_headers .. '\n' .. 96 | sign_headers .. '\n' .. 97 | sha256_hex(payload) 98 | 99 | return cstr, sign_headers 100 | end 101 | 102 | 103 | 104 | _M.new_canonical_request = canonical_req 105 | _M.hash = sha256_hex 106 | 107 | 108 | 109 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 110 | local function amz_date() 111 | local date = ngx.re.gsub(ngx.utctime(), '(-|:)', '') 112 | 113 | return string.format('%sT%sZ', 114 | string.sub(date, 1, 8), 115 | string.sub(date, 10, string.len(date))) 116 | end 117 | 118 | 119 | 120 | -- @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html 121 | local function date() 122 | local d = ngx.re.gsub(ngx.utctime(), '-', '') 123 | return string.sub(d, 1, 8) 124 | end 125 | 126 | 127 | 128 | _M.amz_date = amz_date 129 | _M.date = date 130 | 131 | 132 | 133 | local function str_to_sign(canonical_hash, headers, region, service) 134 | local amz_d 135 | 136 | for i = 1, #headers do 137 | if string.lower(headers[i][1]) == 'x-amz-date' then 138 | amz_d = headers[i][2] 139 | end 140 | end 141 | 142 | if not amz_d then 143 | amz_d = amz_date() 144 | table.insert(headers, { 'x-amz-date', amz_d }) 145 | end 146 | 147 | return 'AWS4-HMAC-SHA256\n' .. 148 | amz_d .. '\n' .. 149 | string.sub(amz_d, 1, 8) .. '/' .. region .. '/' .. service .. '/aws4_request\n' .. 150 | canonical_hash 151 | end 152 | 153 | 154 | 155 | _M.str_to_sign = str_to_sign 156 | 157 | 158 | 159 | local function derive_key(aws_secret, d, region, service) 160 | local ord = { region, service, 'aws4_request' } 161 | local len = #ord 162 | local k 163 | 164 | k = hmac_sha256('AWS4' .. aws_secret, d) 165 | 166 | for i=1, len do 167 | k = hmac_sha256(k, ord[i]) 168 | end 169 | 170 | return k 171 | end 172 | 173 | 174 | 175 | function _M.new_signature(aws_secret, d, region, service, data) 176 | return str.to_hex(hmac_sha256(derive_key(aws_secret, d, region, service), data)) 177 | end 178 | 179 | 180 | 181 | function _M.new_auth_header(cred, signed_headers, d, region, service, data) 182 | local signature = _M.new_signature(cred.secret, d, region, service, data) 183 | return 'AWS4-HMAC-SHA256 Credential=' .. cred.key .. '/' .. d .. '/' .. region .. '/' .. service .. '/aws4_request, SignedHeaders=' .. signed_headers .. ', Signature=' .. signature 184 | end 185 | 186 | 187 | 188 | return _M 189 | -------------------------------------------------------------------------------- /test/request_spec.lua: -------------------------------------------------------------------------------- 1 | local pp = require 'pl.pretty' 2 | local dir = require 'pl.dir' 3 | local file = require 'pl.file' 4 | local path = require 'pl.path' 5 | local stringx = require 'pl.stringx' 6 | local signature = require 'src.signature' 7 | 8 | local function parse_req(req) 9 | local lines = stringx.split(req, '\n') 10 | local method = stringx.split(lines[1], ' ')[1] 11 | local p = stringx.split(lines[1], ' ')[2] 12 | local queries = {} 13 | local headers = {} 14 | local body = {} 15 | local datetime 16 | local in_body = false 17 | 18 | if string.find(p, '?') then 19 | local segs = stringx.split(p, '?') 20 | local args = ngx.decode_args(segs[2]) 21 | local ks = {} 22 | for k, v in pairs(args) do 23 | table.insert(ks, k) 24 | end 25 | table.sort(ks) 26 | for i, k in ipairs(ks) do 27 | queries[i] = { k, args[k] } 28 | end 29 | 30 | p = segs[1] 31 | end 32 | 33 | for i = 2, #lines do 34 | if in_body then 35 | table.insert(body, lines[i]) 36 | elseif not string.find(lines[i], ":") then 37 | in_body = true 38 | else 39 | if string.lower(stringx.split(lines[i], ':')[1]) == 'x-amz-date' then 40 | datetime = stringx.split(lines[i], ':')[2] 41 | end 42 | table.insert(headers, { 43 | stringx.split(lines[i], ':')[1], 44 | stringx.split(lines[i], ':')[2] 45 | }) 46 | end 47 | end 48 | 49 | return { 50 | datetime = datetime, 51 | method = method, 52 | path = p, 53 | headers = headers, 54 | queries = queries, 55 | body = table.concat(body, '\n') 56 | } 57 | end 58 | 59 | 60 | local dirs = dir.getdirectories('./test/aws4_testsuite') 61 | local tests = {} 62 | local to_read = { 63 | { 'authz' }, 64 | { 'creq' }, 65 | { 'req', parse_req }, 66 | { 'sreq' }, 67 | { 'sts' } 68 | } 69 | 70 | for i = 1, #dirs do 71 | local base = dirs[i] 72 | local name = path.basename(dirs[i]) 73 | local should_insert = false 74 | local test = { 75 | name = name 76 | } 77 | 78 | for j = 1, #to_read do 79 | local content = file.read(base .. '/' .. name .. '.' .. to_read[j][1]) 80 | if content then 81 | should_insert = true 82 | if to_read[j][2] then 83 | content = to_read[j][2](content) 84 | end 85 | test[to_read[j][1]] = content 86 | end 87 | end 88 | 89 | if should_insert then 90 | table.insert(tests, test) 91 | end 92 | end 93 | 94 | 95 | 96 | describe('Signature v4', function() 97 | describe('canonical req', function() 98 | for i = 1, #tests do 99 | it('canonical ' .. tests[i].name, function () 100 | local test = tests[i] 101 | local req = test.req 102 | local creq = test.creq 103 | assert.are.equal(signature.new_canonical_request( 104 | req.method, 105 | req.path, 106 | req.queries, 107 | req.headers, 108 | req.body 109 | ), creq) 110 | end) 111 | end 112 | end) 113 | 114 | describe('string to sign', function() 115 | for i = 1, #tests do 116 | it('sts ' .. tests[i].name, function () 117 | local test = tests[i] 118 | local req = test.req 119 | local creq = signature.new_canonical_request( 120 | req.method, 121 | req.path, 122 | req.queries, 123 | req.headers, 124 | req.body 125 | ) 126 | local chash = signature.hash(creq) 127 | local sts = signature.str_to_sign(chash, req.headers, 'us-east-1', 'service') 128 | assert.are.equal(sts, test.sts) 129 | end) 130 | end 131 | end) 132 | 133 | describe('create sign header', function() 134 | for i = 1, #tests do 135 | it('sts ' .. tests[i].name, function () 136 | local test = tests[i] 137 | local req = test.req 138 | local creq = signature.new_canonical_request( 139 | req.method, 140 | req.path, 141 | req.queries, 142 | req.headers, 143 | req.body 144 | ) 145 | local chash = signature.hash(creq) 146 | local sts = signature.str_to_sign(chash, req.headers, 'us-east-1', 'service') 147 | assert.are.equal(sts, test.sts) 148 | end) 149 | end 150 | end) 151 | 152 | describe('auth header', function() 153 | for i = 1, #tests do 154 | it('authz ' .. tests[i].name, function () 155 | local test = tests[i] 156 | local req = test.req 157 | local date = string.sub(req.datetime, 1, 8) 158 | local creq, signed_headers = signature.new_canonical_request( 159 | req.method, 160 | req.path, 161 | req.queries, 162 | req.headers, 163 | req.body 164 | ) 165 | local chash = signature.hash(creq) 166 | local sts = signature.str_to_sign(chash, req.headers, 'us-east-1', 'service') 167 | local authz = signature.new_auth_header({ key = 'AKIDEXAMPLE', secret = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY' }, signed_headers, date, 'us-east-1', 'service', sts) 168 | assert.are.equal(authz, test.authz) 169 | end) 170 | end 171 | end) 172 | end) 173 | 174 | -------------------------------------------------------------------------------- /codegen/service.lua: -------------------------------------------------------------------------------- 1 | local ngx = require 'ngx' 2 | local json = require 'cjson' 3 | local lfs = require 'lfs' 4 | local template = require 'pl.template' 5 | local dir = require 'pl.dir' 6 | local path = require 'pl.path' 7 | local file = require 'pl.file' 8 | local stringx = require 'pl.stringx' 9 | 10 | local f, e = io.open(lfs.currentdir() .. '/botocore/botocore/data/endpoints.json') 11 | 12 | if not f then 13 | print(e) 14 | return 15 | end 16 | 17 | local endpoints = json.decode(f:read('*a')) 18 | 19 | f:close() 20 | 21 | local partition = endpoints.partitions[1] 22 | 23 | local function regions_for_service(name) 24 | local services = partition.services 25 | local service = services[name] 26 | local eps = service['endpoints'] 27 | 28 | local regions = {} 29 | for region_name, _ in pairs(eps) do 30 | table.insert(regions, region_name) 31 | end 32 | 33 | return regions 34 | end 35 | 36 | 37 | local function merge(tbs) 38 | local target = {} 39 | local tb 40 | for i = 1, #tbs do 41 | tb = tbs[i] 42 | if tb then 43 | for k, v in pairs(tb) do 44 | target[k] = v 45 | end 46 | end 47 | end 48 | 49 | return target 50 | end 51 | 52 | 53 | local function find_prop(tbs, prop_name) 54 | local tb 55 | for i = 1, #tbs do 56 | tb = tbs[i] 57 | if tb[prop_name] then 58 | return tb[prop_name] 59 | end 60 | end 61 | return nil 62 | end 63 | 64 | local function endpoints_for_service(name) 65 | local services = partition.services 66 | local service = services[name] 67 | local eps = service['endpoints'] 68 | 69 | local lines = {} 70 | local defaults 71 | for region_name, _ in pairs(eps) do 72 | defaults = merge({ 73 | partition.defaults, 74 | service.defaults, 75 | endpoints[region_name] 76 | }) 77 | 78 | local ep = ngx.re.gsub(defaults.hostname, '{([a-zA-Z]+)}', function(m) 79 | local res = find_prop({ { region = region_name, service = name }, eps[region_name], service, partition }, m[1]) 80 | return res 81 | end) 82 | 83 | table.insert(lines,{ region_name, ep }) 84 | end 85 | 86 | return lines 87 | end 88 | 89 | 90 | 91 | local function load_api_spec(name) 92 | local versions = dir.getdirectories(lfs.currentdir() .. '/botocore/botocore/data/' .. name) 93 | 94 | table.sort(versions, function (a, b) 95 | a = ngx.re.gsub(path.basename(a), '-', '') 96 | b = ngx.re.gsub(path.basename(b), '-', '') 97 | return tonumber(a) > tonumber(b) 98 | end) 99 | 100 | local spec = json.decode(file.read(versions[1] .. '/service-2.json')) 101 | 102 | return spec 103 | end 104 | 105 | 106 | 107 | local function parse_protocol(spec) 108 | local proto = spec.metadata.protocol 109 | if string.find(proto, 'json') then 110 | return 'application/json' 111 | elseif string.find(proto, 'xml') then 112 | return 'application/xml' 113 | else 114 | return 'application/xml' 115 | end 116 | end 117 | 118 | local pp = require 'pl.pretty' 119 | 120 | local function build_uri(segements) 121 | local len = #segements 122 | local res = "" 123 | local in_str = false 124 | 125 | local seg 126 | if #segements == 0 then 127 | return "'/'" 128 | end 129 | for i = 1, len do 130 | seg = segements[i] 131 | if seg.type == 'text' then 132 | if in_str then 133 | if #seg.value then 134 | res = res .. '/' .. seg.value 135 | end 136 | else 137 | if #seg.value then 138 | if i > 1 then 139 | res = res .. " .. " 140 | end 141 | res = res .. "'/" .. seg.value 142 | end 143 | end 144 | 145 | if i == len then 146 | res = res .. "'" 147 | end 148 | in_str = true 149 | elseif seg.type == 'var' then 150 | if in_str then 151 | res = res .. "/' .. " .. seg.value 152 | else 153 | if i == 1 then 154 | res = res .. "'/' .. " .. seg.value 155 | else 156 | res = res .. " .. '/' .. " .. seg.value 157 | end 158 | end 159 | in_str = false 160 | elseif seg.type == 'query_action' then 161 | res = res .. " .. '?" .. seg.value .. "'" 162 | end 163 | end 164 | 165 | return res 166 | end 167 | 168 | 169 | 170 | local function parse_uri(uri) 171 | local segs = stringx.split(uri, '/') 172 | local res = {} 173 | local query_action 174 | local last = segs[#segs] 175 | 176 | if string.find(last, '?') then 177 | local sep = stringx.split(last, '?') 178 | segs[#segs] = sep[1] 179 | query_action = sep[2] 180 | end 181 | 182 | for i, seg in ipairs(segs) do 183 | if #seg > 0 then 184 | if string.find(seg, '{') then 185 | table.insert(res, { type = 'var', value = ngx.re.gsub(seg, '({|}|\\+)', '') }) 186 | else 187 | table.insert(res, { type = 'text', value = seg }) 188 | end 189 | end 190 | end 191 | 192 | if query_action then 193 | table.insert(res, { type = 'query_action', value = query_action }) 194 | end 195 | 196 | return res 197 | end 198 | 199 | 200 | local function render_method(env) 201 | local tpl = file.read(lfs.currentdir() .. '/method_tpl.lua') 202 | return template.substitute(tpl, env) 203 | end 204 | 205 | 206 | local function render_spec(spec) 207 | local ops = spec.operations 208 | local shapes = spec.shapes 209 | 210 | local input, shape 211 | local uri_params, queries, headers 212 | local blocks = {} 213 | for _, operation in pairs(ops) do 214 | uri_params = {} 215 | queries = {} 216 | headers = { "'X-Amz-Date'", "'Host'", "'X-Amz-Security-Token'" } 217 | input = operation.input 218 | 219 | local uri_exp = build_uri(parse_uri(operation.http.requestUri)) 220 | 221 | if input and input.shape then 222 | shape = shapes[input.shape] 223 | 224 | if shape.type == 'structure' then 225 | for member_name, member_value in pairs(shape.members) do 226 | if member_value.location == 'uri' then 227 | table.insert(uri_params, member_name) 228 | elseif member_value.location == 'querystring' then 229 | table.insert(queries, "'" .. member_value.locationName .. "'") 230 | elseif member_value.location == 'header' then 231 | table.insert(headers, "'" .. member_value.locationName .. "'") 232 | end 233 | end 234 | end 235 | end 236 | 237 | table.sort(queries) 238 | table.sort(headers) 239 | 240 | table.insert(blocks, render_method(merge({ _G, { 241 | NAME = operation.name, 242 | ARGS = table.concat({ 'cred', 'opts' }, ', '), 243 | URI = uri_exp, 244 | METHOD = operation.http.method, 245 | URI_PARAMS = uri_params, 246 | QUERIES = queries, 247 | HEADERS = headers, 248 | OK_RESPONSE_CODE = operation.http.responseCode, 249 | }}))) 250 | end 251 | 252 | return table.concat(blocks, '\n\n\n') 253 | end 254 | 255 | 256 | 257 | local function render(name) 258 | local tpl_f = io.open(lfs.currentdir() .. '/tpl.lua') 259 | local tpl = tpl_f:read('*a') 260 | tpl_f:close() 261 | local spec = load_api_spec(name) 262 | 263 | local env = { 264 | API_VERSION = spec.metadata.apiVersion, 265 | SIGNATURE_VERSION = spec.metadata.signatureVersion, 266 | CONTENT_TYPE = parse_protocol(spec), 267 | NAME = name, 268 | REGIONS = regions_for_service(name), 269 | ENDPOINTS = endpoints_for_service(name), 270 | METHODS = render_spec(spec) 271 | } 272 | 273 | 274 | return template.substitute(tpl, merge({ _G, env })) 275 | end 276 | 277 | 278 | return render 279 | -------------------------------------------------------------------------------- /lib/resty/aws/sqs.lua: -------------------------------------------------------------------------------- 1 | -- 2 | --- @module resty.aws.sqs 3 | 4 | local _M = {} 5 | local http = require 'resty.http' 6 | local request = require 'resty.aws.request' 7 | 8 | local VERSION = '2012-11-05' 9 | local CONTENT_TYPE = 'application/xml' 10 | local SIGNATURE_VERSION = 'v4' 11 | 12 | local REGIONS = { 13 | ['ap-southeast-1'] = 'ap-southeast-1', 14 | ['ap-northeast-2'] = 'ap-northeast-2', 15 | ['ap-northeast-1'] = 'ap-northeast-1', 16 | ['us-east-2'] = 'us-east-2', 17 | ['ap-south-1'] = 'ap-south-1', 18 | ['us-west-2'] = 'us-west-2', 19 | ['us-east-1'] = 'us-east-1', 20 | ['eu-central-1'] = 'eu-central-1', 21 | ['eu-west-1'] = 'eu-west-1', 22 | ['sa-east-1'] = 'sa-east-1', 23 | ['us-west-1'] = 'us-west-1', 24 | ['ap-southeast-2'] = 'ap-southeast-2', 25 | } 26 | 27 | local ENDPOINTS = { 28 | ['ap-southeast-1'] = 'sqs.ap-southeast-1.amazonaws.com', 29 | ['ap-northeast-2'] = 'sqs.ap-northeast-2.amazonaws.com', 30 | ['ap-northeast-1'] = 'sqs.ap-northeast-1.amazonaws.com', 31 | ['us-east-2'] = 'sqs.us-east-2.amazonaws.com', 32 | ['ap-south-1'] = 'sqs.ap-south-1.amazonaws.com', 33 | ['us-west-2'] = 'sqs.us-west-2.amazonaws.com', 34 | ['us-east-1'] = 'sqs.us-east-1.amazonaws.com', 35 | ['eu-central-1'] = 'sqs.eu-central-1.amazonaws.com', 36 | ['eu-west-1'] = 'sqs.eu-west-1.amazonaws.com', 37 | ['sa-east-1'] = 'sqs.sa-east-1.amazonaws.com', 38 | ['us-west-1'] = 'sqs.us-west-1.amazonaws.com', 39 | ['ap-southeast-2'] = 'sqs.ap-southeast-2.amazonaws.com', 40 | } 41 | 42 | local mt = { __index = _M } 43 | 44 | function _M.new(_, region) 45 | local r = string.lower(region or os.getenv('AWS_DEFAULT_REGION')) 46 | 47 | if not r then 48 | return nil, '[sqs] region[' .. region .. '] is not available for this service' 49 | end 50 | 51 | return setmetatable({ 52 | service = 'sqs', 53 | scope = r .. '/sqs/aws4_request', 54 | host = ENDPOINTS[r] 55 | }, mt) 56 | end 57 | 58 | 59 | local DELETEQUEUE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 60 | function _M.DeleteQueue(self, cred, opts, data) 61 | return request({ 62 | signature_version = SIGNATURE_VERSION, 63 | version = VERSION, 64 | service = self.service, 65 | host = self.host, 66 | scope = self.scope, 67 | action = 'DeleteQueue', 68 | method = 'POST', 69 | cred = cred, 70 | content_type = CONTENT_TYPE, 71 | pathname = '/', 72 | body = data or '', 73 | header_keys = DELETEQUEUE_HEADER_KEYS, 74 | header_data = opts, 75 | }) 76 | end 77 | 78 | 79 | 80 | local PURGEQUEUE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 81 | function _M.PurgeQueue(self, cred, opts, data) 82 | return request({ 83 | signature_version = SIGNATURE_VERSION, 84 | version = VERSION, 85 | service = self.service, 86 | host = self.host, 87 | scope = self.scope, 88 | action = 'PurgeQueue', 89 | method = 'POST', 90 | cred = cred, 91 | content_type = CONTENT_TYPE, 92 | pathname = '/', 93 | body = data or '', 94 | header_keys = PURGEQUEUE_HEADER_KEYS, 95 | header_data = opts, 96 | }) 97 | end 98 | 99 | 100 | 101 | local SENDMESSAGEBATCH_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 102 | function _M.SendMessageBatch(self, cred, opts, data) 103 | return request({ 104 | signature_version = SIGNATURE_VERSION, 105 | version = VERSION, 106 | service = self.service, 107 | host = self.host, 108 | scope = self.scope, 109 | action = 'SendMessageBatch', 110 | method = 'POST', 111 | cred = cred, 112 | content_type = CONTENT_TYPE, 113 | pathname = '/', 114 | body = data or '', 115 | header_keys = SENDMESSAGEBATCH_HEADER_KEYS, 116 | header_data = opts, 117 | }) 118 | end 119 | 120 | 121 | 122 | local DELETEMESSAGEBATCH_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 123 | function _M.DeleteMessageBatch(self, cred, opts, data) 124 | return request({ 125 | signature_version = SIGNATURE_VERSION, 126 | version = VERSION, 127 | service = self.service, 128 | host = self.host, 129 | scope = self.scope, 130 | action = 'DeleteMessageBatch', 131 | method = 'POST', 132 | cred = cred, 133 | content_type = CONTENT_TYPE, 134 | pathname = '/', 135 | body = data or '', 136 | header_keys = DELETEMESSAGEBATCH_HEADER_KEYS, 137 | header_data = opts, 138 | }) 139 | end 140 | 141 | 142 | 143 | local GETQUEUEATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 144 | function _M.GetQueueAttributes(self, cred, opts, data) 145 | return request({ 146 | signature_version = SIGNATURE_VERSION, 147 | version = VERSION, 148 | service = self.service, 149 | host = self.host, 150 | scope = self.scope, 151 | action = 'GetQueueAttributes', 152 | method = 'POST', 153 | cred = cred, 154 | content_type = CONTENT_TYPE, 155 | pathname = '/', 156 | body = data or '', 157 | header_keys = GETQUEUEATTRIBUTES_HEADER_KEYS, 158 | header_data = opts, 159 | }) 160 | end 161 | 162 | 163 | 164 | local SETQUEUEATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 165 | function _M.SetQueueAttributes(self, cred, opts, data) 166 | return request({ 167 | signature_version = SIGNATURE_VERSION, 168 | version = VERSION, 169 | service = self.service, 170 | host = self.host, 171 | scope = self.scope, 172 | action = 'SetQueueAttributes', 173 | method = 'POST', 174 | cred = cred, 175 | content_type = CONTENT_TYPE, 176 | pathname = '/', 177 | body = data or '', 178 | header_keys = SETQUEUEATTRIBUTES_HEADER_KEYS, 179 | header_data = opts, 180 | }) 181 | end 182 | 183 | 184 | 185 | local SENDMESSAGE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 186 | function _M.SendMessage(self, cred, opts, data) 187 | return request({ 188 | signature_version = SIGNATURE_VERSION, 189 | version = VERSION, 190 | service = self.service, 191 | host = self.host, 192 | scope = self.scope, 193 | action = 'SendMessage', 194 | method = 'POST', 195 | cred = cred, 196 | content_type = CONTENT_TYPE, 197 | pathname = '/', 198 | body = data or '', 199 | header_keys = SENDMESSAGE_HEADER_KEYS, 200 | header_data = opts, 201 | }) 202 | end 203 | 204 | 205 | 206 | local CREATEQUEUE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 207 | function _M.CreateQueue(self, cred, opts, data) 208 | return request({ 209 | signature_version = SIGNATURE_VERSION, 210 | version = VERSION, 211 | service = self.service, 212 | host = self.host, 213 | scope = self.scope, 214 | action = 'CreateQueue', 215 | method = 'POST', 216 | cred = cred, 217 | content_type = CONTENT_TYPE, 218 | pathname = '/', 219 | body = data or '', 220 | header_keys = CREATEQUEUE_HEADER_KEYS, 221 | header_data = opts, 222 | }) 223 | end 224 | 225 | 226 | 227 | local GETQUEUEURL_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 228 | function _M.GetQueueUrl(self, cred, opts, data) 229 | return request({ 230 | signature_version = SIGNATURE_VERSION, 231 | version = VERSION, 232 | service = self.service, 233 | host = self.host, 234 | scope = self.scope, 235 | action = 'GetQueueUrl', 236 | method = 'POST', 237 | cred = cred, 238 | content_type = CONTENT_TYPE, 239 | pathname = '/', 240 | body = data or '', 241 | header_keys = GETQUEUEURL_HEADER_KEYS, 242 | header_data = opts, 243 | }) 244 | end 245 | 246 | 247 | 248 | local CHANGEMESSAGEVISIBILITY_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 249 | function _M.ChangeMessageVisibility(self, cred, opts, data) 250 | return request({ 251 | signature_version = SIGNATURE_VERSION, 252 | version = VERSION, 253 | service = self.service, 254 | host = self.host, 255 | scope = self.scope, 256 | action = 'ChangeMessageVisibility', 257 | method = 'POST', 258 | cred = cred, 259 | content_type = CONTENT_TYPE, 260 | pathname = '/', 261 | body = data or '', 262 | header_keys = CHANGEMESSAGEVISIBILITY_HEADER_KEYS, 263 | header_data = opts, 264 | }) 265 | end 266 | 267 | 268 | 269 | local REMOVEPERMISSION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 270 | function _M.RemovePermission(self, cred, opts, data) 271 | return request({ 272 | signature_version = SIGNATURE_VERSION, 273 | version = VERSION, 274 | service = self.service, 275 | host = self.host, 276 | scope = self.scope, 277 | action = 'RemovePermission', 278 | method = 'POST', 279 | cred = cred, 280 | content_type = CONTENT_TYPE, 281 | pathname = '/', 282 | body = data or '', 283 | header_keys = REMOVEPERMISSION_HEADER_KEYS, 284 | header_data = opts, 285 | }) 286 | end 287 | 288 | 289 | 290 | local DELETEMESSAGE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 291 | function _M.DeleteMessage(self, cred, opts, data) 292 | return request({ 293 | signature_version = SIGNATURE_VERSION, 294 | version = VERSION, 295 | service = self.service, 296 | host = self.host, 297 | scope = self.scope, 298 | action = 'DeleteMessage', 299 | method = 'POST', 300 | cred = cred, 301 | content_type = CONTENT_TYPE, 302 | pathname = '/', 303 | body = data or '', 304 | header_keys = DELETEMESSAGE_HEADER_KEYS, 305 | header_data = opts, 306 | }) 307 | end 308 | 309 | 310 | 311 | local CHANGEMESSAGEVISIBILITYBATCH_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 312 | function _M.ChangeMessageVisibilityBatch(self, cred, opts, data) 313 | return request({ 314 | signature_version = SIGNATURE_VERSION, 315 | version = VERSION, 316 | service = self.service, 317 | host = self.host, 318 | scope = self.scope, 319 | action = 'ChangeMessageVisibilityBatch', 320 | method = 'POST', 321 | cred = cred, 322 | content_type = CONTENT_TYPE, 323 | pathname = '/', 324 | body = data or '', 325 | header_keys = CHANGEMESSAGEVISIBILITYBATCH_HEADER_KEYS, 326 | header_data = opts, 327 | }) 328 | end 329 | 330 | 331 | 332 | local LISTQUEUES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 333 | function _M.ListQueues(self, cred, opts, data) 334 | return request({ 335 | signature_version = SIGNATURE_VERSION, 336 | version = VERSION, 337 | service = self.service, 338 | host = self.host, 339 | scope = self.scope, 340 | action = 'ListQueues', 341 | method = 'POST', 342 | cred = cred, 343 | content_type = CONTENT_TYPE, 344 | pathname = '/', 345 | body = data or '', 346 | header_keys = LISTQUEUES_HEADER_KEYS, 347 | header_data = opts, 348 | }) 349 | end 350 | 351 | 352 | 353 | local ADDPERMISSION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 354 | function _M.AddPermission(self, cred, opts, data) 355 | return request({ 356 | signature_version = SIGNATURE_VERSION, 357 | version = VERSION, 358 | service = self.service, 359 | host = self.host, 360 | scope = self.scope, 361 | action = 'AddPermission', 362 | method = 'POST', 363 | cred = cred, 364 | content_type = CONTENT_TYPE, 365 | pathname = '/', 366 | body = data or '', 367 | header_keys = ADDPERMISSION_HEADER_KEYS, 368 | header_data = opts, 369 | }) 370 | end 371 | 372 | 373 | 374 | local RECEIVEMESSAGE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 375 | function _M.ReceiveMessage(self, cred, opts, data) 376 | return request({ 377 | signature_version = SIGNATURE_VERSION, 378 | version = VERSION, 379 | service = self.service, 380 | host = self.host, 381 | scope = self.scope, 382 | action = 'ReceiveMessage', 383 | method = 'POST', 384 | cred = cred, 385 | content_type = CONTENT_TYPE, 386 | pathname = '/', 387 | body = data or '', 388 | header_keys = RECEIVEMESSAGE_HEADER_KEYS, 389 | header_data = opts, 390 | }) 391 | end 392 | 393 | 394 | 395 | local LISTDEADLETTERSOURCEQUEUES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 396 | function _M.ListDeadLetterSourceQueues(self, cred, opts, data) 397 | return request({ 398 | signature_version = SIGNATURE_VERSION, 399 | version = VERSION, 400 | service = self.service, 401 | host = self.host, 402 | scope = self.scope, 403 | action = 'ListDeadLetterSourceQueues', 404 | method = 'POST', 405 | cred = cred, 406 | content_type = CONTENT_TYPE, 407 | pathname = '/', 408 | body = data or '', 409 | header_keys = LISTDEADLETTERSOURCEQUEUES_HEADER_KEYS, 410 | header_data = opts, 411 | }) 412 | end 413 | 414 | 415 | 416 | return _M 417 | 418 | 419 | -------------------------------------------------------------------------------- /lib/resty/aws/sns.lua: -------------------------------------------------------------------------------- 1 | -- 2 | --- @module resty.aws.sns 3 | 4 | local _M = {} 5 | local http = require 'resty.http' 6 | local request = require 'resty.aws.request' 7 | 8 | local VERSION = '2010-03-31' 9 | local CONTENT_TYPE = 'application/xml' 10 | local SIGNATURE_VERSION = 'v4' 11 | 12 | local REGIONS = { 13 | ['ap-southeast-1'] = 'ap-southeast-1', 14 | ['ap-northeast-2'] = 'ap-northeast-2', 15 | ['ap-northeast-1'] = 'ap-northeast-1', 16 | ['us-east-2'] = 'us-east-2', 17 | ['ap-south-1'] = 'ap-south-1', 18 | ['us-west-2'] = 'us-west-2', 19 | ['us-east-1'] = 'us-east-1', 20 | ['eu-central-1'] = 'eu-central-1', 21 | ['eu-west-1'] = 'eu-west-1', 22 | ['sa-east-1'] = 'sa-east-1', 23 | ['us-west-1'] = 'us-west-1', 24 | ['ap-southeast-2'] = 'ap-southeast-2', 25 | } 26 | 27 | local ENDPOINTS = { 28 | ['ap-southeast-1'] = 'sns.ap-southeast-1.amazonaws.com', 29 | ['ap-northeast-2'] = 'sns.ap-northeast-2.amazonaws.com', 30 | ['ap-northeast-1'] = 'sns.ap-northeast-1.amazonaws.com', 31 | ['us-east-2'] = 'sns.us-east-2.amazonaws.com', 32 | ['ap-south-1'] = 'sns.ap-south-1.amazonaws.com', 33 | ['us-west-2'] = 'sns.us-west-2.amazonaws.com', 34 | ['us-east-1'] = 'sns.us-east-1.amazonaws.com', 35 | ['eu-central-1'] = 'sns.eu-central-1.amazonaws.com', 36 | ['eu-west-1'] = 'sns.eu-west-1.amazonaws.com', 37 | ['sa-east-1'] = 'sns.sa-east-1.amazonaws.com', 38 | ['us-west-1'] = 'sns.us-west-1.amazonaws.com', 39 | ['ap-southeast-2'] = 'sns.ap-southeast-2.amazonaws.com', 40 | } 41 | 42 | local mt = { __index = _M } 43 | 44 | function _M.new(_, region) 45 | local r = string.lower(region or os.getenv('AWS_DEFAULT_REGION')) 46 | 47 | if not r then 48 | return nil, '[sns] region[' .. region .. '] is not available for this service' 49 | end 50 | 51 | return setmetatable({ 52 | service = 'sns', 53 | scope = r .. '/sns/aws4_request', 54 | host = ENDPOINTS[r] 55 | }, mt) 56 | end 57 | 58 | 59 | local CONFIRMSUBSCRIPTION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 60 | function _M.ConfirmSubscription(self, cred, opts, data) 61 | return request({ 62 | signature_version = SIGNATURE_VERSION, 63 | version = VERSION, 64 | service = self.service, 65 | host = self.host, 66 | scope = self.scope, 67 | action = 'ConfirmSubscription', 68 | method = 'POST', 69 | cred = cred, 70 | content_type = CONTENT_TYPE, 71 | pathname = '/', 72 | body = data or '', 73 | header_keys = CONFIRMSUBSCRIPTION_HEADER_KEYS, 74 | header_data = opts, 75 | }) 76 | end 77 | 78 | 79 | 80 | local CREATETOPIC_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 81 | function _M.CreateTopic(self, cred, opts, data) 82 | return request({ 83 | signature_version = SIGNATURE_VERSION, 84 | version = VERSION, 85 | service = self.service, 86 | host = self.host, 87 | scope = self.scope, 88 | action = 'CreateTopic', 89 | method = 'POST', 90 | cred = cred, 91 | content_type = CONTENT_TYPE, 92 | pathname = '/', 93 | body = data or '', 94 | header_keys = CREATETOPIC_HEADER_KEYS, 95 | header_data = opts, 96 | }) 97 | end 98 | 99 | 100 | 101 | local CHECKIFPHONENUMBERISOPTEDOUT_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 102 | function _M.CheckIfPhoneNumberIsOptedOut(self, cred, opts, data) 103 | return request({ 104 | signature_version = SIGNATURE_VERSION, 105 | version = VERSION, 106 | service = self.service, 107 | host = self.host, 108 | scope = self.scope, 109 | action = 'CheckIfPhoneNumberIsOptedOut', 110 | method = 'POST', 111 | cred = cred, 112 | content_type = CONTENT_TYPE, 113 | pathname = '/', 114 | body = data or '', 115 | header_keys = CHECKIFPHONENUMBERISOPTEDOUT_HEADER_KEYS, 116 | header_data = opts, 117 | }) 118 | end 119 | 120 | 121 | 122 | local GETENDPOINTATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 123 | function _M.GetEndpointAttributes(self, cred, opts, data) 124 | return request({ 125 | signature_version = SIGNATURE_VERSION, 126 | version = VERSION, 127 | service = self.service, 128 | host = self.host, 129 | scope = self.scope, 130 | action = 'GetEndpointAttributes', 131 | method = 'POST', 132 | cred = cred, 133 | content_type = CONTENT_TYPE, 134 | pathname = '/', 135 | body = data or '', 136 | header_keys = GETENDPOINTATTRIBUTES_HEADER_KEYS, 137 | header_data = opts, 138 | }) 139 | end 140 | 141 | 142 | 143 | local DELETEPLATFORMAPPLICATION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 144 | function _M.DeletePlatformApplication(self, cred, opts, data) 145 | return request({ 146 | signature_version = SIGNATURE_VERSION, 147 | version = VERSION, 148 | service = self.service, 149 | host = self.host, 150 | scope = self.scope, 151 | action = 'DeletePlatformApplication', 152 | method = 'POST', 153 | cred = cred, 154 | content_type = CONTENT_TYPE, 155 | pathname = '/', 156 | body = data or '', 157 | header_keys = DELETEPLATFORMAPPLICATION_HEADER_KEYS, 158 | header_data = opts, 159 | }) 160 | end 161 | 162 | 163 | 164 | local DELETETOPIC_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 165 | function _M.DeleteTopic(self, cred, opts, data) 166 | return request({ 167 | signature_version = SIGNATURE_VERSION, 168 | version = VERSION, 169 | service = self.service, 170 | host = self.host, 171 | scope = self.scope, 172 | action = 'DeleteTopic', 173 | method = 'POST', 174 | cred = cred, 175 | content_type = CONTENT_TYPE, 176 | pathname = '/', 177 | body = data or '', 178 | header_keys = DELETETOPIC_HEADER_KEYS, 179 | header_data = opts, 180 | }) 181 | end 182 | 183 | 184 | 185 | local GETSMSATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 186 | function _M.GetSMSAttributes(self, cred, opts, data) 187 | return request({ 188 | signature_version = SIGNATURE_VERSION, 189 | version = VERSION, 190 | service = self.service, 191 | host = self.host, 192 | scope = self.scope, 193 | action = 'GetSMSAttributes', 194 | method = 'POST', 195 | cred = cred, 196 | content_type = CONTENT_TYPE, 197 | pathname = '/', 198 | body = data or '', 199 | header_keys = GETSMSATTRIBUTES_HEADER_KEYS, 200 | header_data = opts, 201 | }) 202 | end 203 | 204 | 205 | 206 | local LISTENDPOINTSBYPLATFORMAPPLICATION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 207 | function _M.ListEndpointsByPlatformApplication(self, cred, opts, data) 208 | return request({ 209 | signature_version = SIGNATURE_VERSION, 210 | version = VERSION, 211 | service = self.service, 212 | host = self.host, 213 | scope = self.scope, 214 | action = 'ListEndpointsByPlatformApplication', 215 | method = 'POST', 216 | cred = cred, 217 | content_type = CONTENT_TYPE, 218 | pathname = '/', 219 | body = data or '', 220 | header_keys = LISTENDPOINTSBYPLATFORMAPPLICATION_HEADER_KEYS, 221 | header_data = opts, 222 | }) 223 | end 224 | 225 | 226 | 227 | local UNSUBSCRIBE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 228 | function _M.Unsubscribe(self, cred, opts, data) 229 | return request({ 230 | signature_version = SIGNATURE_VERSION, 231 | version = VERSION, 232 | service = self.service, 233 | host = self.host, 234 | scope = self.scope, 235 | action = 'Unsubscribe', 236 | method = 'POST', 237 | cred = cred, 238 | content_type = CONTENT_TYPE, 239 | pathname = '/', 240 | body = data or '', 241 | header_keys = UNSUBSCRIBE_HEADER_KEYS, 242 | header_data = opts, 243 | }) 244 | end 245 | 246 | 247 | 248 | local SETPLATFORMAPPLICATIONATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 249 | function _M.SetPlatformApplicationAttributes(self, cred, opts, data) 250 | return request({ 251 | signature_version = SIGNATURE_VERSION, 252 | version = VERSION, 253 | service = self.service, 254 | host = self.host, 255 | scope = self.scope, 256 | action = 'SetPlatformApplicationAttributes', 257 | method = 'POST', 258 | cred = cred, 259 | content_type = CONTENT_TYPE, 260 | pathname = '/', 261 | body = data or '', 262 | header_keys = SETPLATFORMAPPLICATIONATTRIBUTES_HEADER_KEYS, 263 | header_data = opts, 264 | }) 265 | end 266 | 267 | 268 | 269 | local GETSUBSCRIPTIONATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 270 | function _M.GetSubscriptionAttributes(self, cred, opts, data) 271 | return request({ 272 | signature_version = SIGNATURE_VERSION, 273 | version = VERSION, 274 | service = self.service, 275 | host = self.host, 276 | scope = self.scope, 277 | action = 'GetSubscriptionAttributes', 278 | method = 'POST', 279 | cred = cred, 280 | content_type = CONTENT_TYPE, 281 | pathname = '/', 282 | body = data or '', 283 | header_keys = GETSUBSCRIPTIONATTRIBUTES_HEADER_KEYS, 284 | header_data = opts, 285 | }) 286 | end 287 | 288 | 289 | 290 | local SUBSCRIBE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 291 | function _M.Subscribe(self, cred, opts, data) 292 | return request({ 293 | signature_version = SIGNATURE_VERSION, 294 | version = VERSION, 295 | service = self.service, 296 | host = self.host, 297 | scope = self.scope, 298 | action = 'Subscribe', 299 | method = 'POST', 300 | cred = cred, 301 | content_type = CONTENT_TYPE, 302 | pathname = '/', 303 | body = data or '', 304 | header_keys = SUBSCRIBE_HEADER_KEYS, 305 | header_data = opts, 306 | }) 307 | end 308 | 309 | 310 | 311 | local SETTOPICATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 312 | function _M.SetTopicAttributes(self, cred, opts, data) 313 | return request({ 314 | signature_version = SIGNATURE_VERSION, 315 | version = VERSION, 316 | service = self.service, 317 | host = self.host, 318 | scope = self.scope, 319 | action = 'SetTopicAttributes', 320 | method = 'POST', 321 | cred = cred, 322 | content_type = CONTENT_TYPE, 323 | pathname = '/', 324 | body = data or '', 325 | header_keys = SETTOPICATTRIBUTES_HEADER_KEYS, 326 | header_data = opts, 327 | }) 328 | end 329 | 330 | 331 | 332 | local LISTSUBSCRIPTIONSBYTOPIC_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 333 | function _M.ListSubscriptionsByTopic(self, cred, opts, data) 334 | return request({ 335 | signature_version = SIGNATURE_VERSION, 336 | version = VERSION, 337 | service = self.service, 338 | host = self.host, 339 | scope = self.scope, 340 | action = 'ListSubscriptionsByTopic', 341 | method = 'POST', 342 | cred = cred, 343 | content_type = CONTENT_TYPE, 344 | pathname = '/', 345 | body = data or '', 346 | header_keys = LISTSUBSCRIPTIONSBYTOPIC_HEADER_KEYS, 347 | header_data = opts, 348 | }) 349 | end 350 | 351 | 352 | 353 | local LISTPLATFORMAPPLICATIONS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 354 | function _M.ListPlatformApplications(self, cred, opts, data) 355 | return request({ 356 | signature_version = SIGNATURE_VERSION, 357 | version = VERSION, 358 | service = self.service, 359 | host = self.host, 360 | scope = self.scope, 361 | action = 'ListPlatformApplications', 362 | method = 'POST', 363 | cred = cred, 364 | content_type = CONTENT_TYPE, 365 | pathname = '/', 366 | body = data or '', 367 | header_keys = LISTPLATFORMAPPLICATIONS_HEADER_KEYS, 368 | header_data = opts, 369 | }) 370 | end 371 | 372 | 373 | 374 | local OPTINPHONENUMBER_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 375 | function _M.OptInPhoneNumber(self, cred, opts, data) 376 | return request({ 377 | signature_version = SIGNATURE_VERSION, 378 | version = VERSION, 379 | service = self.service, 380 | host = self.host, 381 | scope = self.scope, 382 | action = 'OptInPhoneNumber', 383 | method = 'POST', 384 | cred = cred, 385 | content_type = CONTENT_TYPE, 386 | pathname = '/', 387 | body = data or '', 388 | header_keys = OPTINPHONENUMBER_HEADER_KEYS, 389 | header_data = opts, 390 | }) 391 | end 392 | 393 | 394 | 395 | local CREATEPLATFORMENDPOINT_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 396 | function _M.CreatePlatformEndpoint(self, cred, opts, data) 397 | return request({ 398 | signature_version = SIGNATURE_VERSION, 399 | version = VERSION, 400 | service = self.service, 401 | host = self.host, 402 | scope = self.scope, 403 | action = 'CreatePlatformEndpoint', 404 | method = 'POST', 405 | cred = cred, 406 | content_type = CONTENT_TYPE, 407 | pathname = '/', 408 | body = data or '', 409 | header_keys = CREATEPLATFORMENDPOINT_HEADER_KEYS, 410 | header_data = opts, 411 | }) 412 | end 413 | 414 | 415 | 416 | local SETENDPOINTATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 417 | function _M.SetEndpointAttributes(self, cred, opts, data) 418 | return request({ 419 | signature_version = SIGNATURE_VERSION, 420 | version = VERSION, 421 | service = self.service, 422 | host = self.host, 423 | scope = self.scope, 424 | action = 'SetEndpointAttributes', 425 | method = 'POST', 426 | cred = cred, 427 | content_type = CONTENT_TYPE, 428 | pathname = '/', 429 | body = data or '', 430 | header_keys = SETENDPOINTATTRIBUTES_HEADER_KEYS, 431 | header_data = opts, 432 | }) 433 | end 434 | 435 | 436 | 437 | local DELETEENDPOINT_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 438 | function _M.DeleteEndpoint(self, cred, opts, data) 439 | return request({ 440 | signature_version = SIGNATURE_VERSION, 441 | version = VERSION, 442 | service = self.service, 443 | host = self.host, 444 | scope = self.scope, 445 | action = 'DeleteEndpoint', 446 | method = 'POST', 447 | cred = cred, 448 | content_type = CONTENT_TYPE, 449 | pathname = '/', 450 | body = data or '', 451 | header_keys = DELETEENDPOINT_HEADER_KEYS, 452 | header_data = opts, 453 | }) 454 | end 455 | 456 | 457 | 458 | local REMOVEPERMISSION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 459 | function _M.RemovePermission(self, cred, opts, data) 460 | return request({ 461 | signature_version = SIGNATURE_VERSION, 462 | version = VERSION, 463 | service = self.service, 464 | host = self.host, 465 | scope = self.scope, 466 | action = 'RemovePermission', 467 | method = 'POST', 468 | cred = cred, 469 | content_type = CONTENT_TYPE, 470 | pathname = '/', 471 | body = data or '', 472 | header_keys = REMOVEPERMISSION_HEADER_KEYS, 473 | header_data = opts, 474 | }) 475 | end 476 | 477 | 478 | 479 | local PUBLISH_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 480 | function _M.Publish(self, cred, opts, data) 481 | return request({ 482 | signature_version = SIGNATURE_VERSION, 483 | version = VERSION, 484 | service = self.service, 485 | host = self.host, 486 | scope = self.scope, 487 | action = 'Publish', 488 | method = 'POST', 489 | cred = cred, 490 | content_type = CONTENT_TYPE, 491 | pathname = '/', 492 | body = data or '', 493 | header_keys = PUBLISH_HEADER_KEYS, 494 | header_data = opts, 495 | }) 496 | end 497 | 498 | 499 | 500 | local LISTSUBSCRIPTIONS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 501 | function _M.ListSubscriptions(self, cred, opts, data) 502 | return request({ 503 | signature_version = SIGNATURE_VERSION, 504 | version = VERSION, 505 | service = self.service, 506 | host = self.host, 507 | scope = self.scope, 508 | action = 'ListSubscriptions', 509 | method = 'POST', 510 | cred = cred, 511 | content_type = CONTENT_TYPE, 512 | pathname = '/', 513 | body = data or '', 514 | header_keys = LISTSUBSCRIPTIONS_HEADER_KEYS, 515 | header_data = opts, 516 | }) 517 | end 518 | 519 | 520 | 521 | local SETSUBSCRIPTIONATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 522 | function _M.SetSubscriptionAttributes(self, cred, opts, data) 523 | return request({ 524 | signature_version = SIGNATURE_VERSION, 525 | version = VERSION, 526 | service = self.service, 527 | host = self.host, 528 | scope = self.scope, 529 | action = 'SetSubscriptionAttributes', 530 | method = 'POST', 531 | cred = cred, 532 | content_type = CONTENT_TYPE, 533 | pathname = '/', 534 | body = data or '', 535 | header_keys = SETSUBSCRIPTIONATTRIBUTES_HEADER_KEYS, 536 | header_data = opts, 537 | }) 538 | end 539 | 540 | 541 | 542 | local CREATEPLATFORMAPPLICATION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 543 | function _M.CreatePlatformApplication(self, cred, opts, data) 544 | return request({ 545 | signature_version = SIGNATURE_VERSION, 546 | version = VERSION, 547 | service = self.service, 548 | host = self.host, 549 | scope = self.scope, 550 | action = 'CreatePlatformApplication', 551 | method = 'POST', 552 | cred = cred, 553 | content_type = CONTENT_TYPE, 554 | pathname = '/', 555 | body = data or '', 556 | header_keys = CREATEPLATFORMAPPLICATION_HEADER_KEYS, 557 | header_data = opts, 558 | }) 559 | end 560 | 561 | 562 | 563 | local LISTTOPICS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 564 | function _M.ListTopics(self, cred, opts, data) 565 | return request({ 566 | signature_version = SIGNATURE_VERSION, 567 | version = VERSION, 568 | service = self.service, 569 | host = self.host, 570 | scope = self.scope, 571 | action = 'ListTopics', 572 | method = 'POST', 573 | cred = cred, 574 | content_type = CONTENT_TYPE, 575 | pathname = '/', 576 | body = data or '', 577 | header_keys = LISTTOPICS_HEADER_KEYS, 578 | header_data = opts, 579 | }) 580 | end 581 | 582 | 583 | 584 | local LISTPHONENUMBERSOPTEDOUT_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 585 | function _M.ListPhoneNumbersOptedOut(self, cred, opts, data) 586 | return request({ 587 | signature_version = SIGNATURE_VERSION, 588 | version = VERSION, 589 | service = self.service, 590 | host = self.host, 591 | scope = self.scope, 592 | action = 'ListPhoneNumbersOptedOut', 593 | method = 'POST', 594 | cred = cred, 595 | content_type = CONTENT_TYPE, 596 | pathname = '/', 597 | body = data or '', 598 | header_keys = LISTPHONENUMBERSOPTEDOUT_HEADER_KEYS, 599 | header_data = opts, 600 | }) 601 | end 602 | 603 | 604 | 605 | local SETSMSATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 606 | function _M.SetSMSAttributes(self, cred, opts, data) 607 | return request({ 608 | signature_version = SIGNATURE_VERSION, 609 | version = VERSION, 610 | service = self.service, 611 | host = self.host, 612 | scope = self.scope, 613 | action = 'SetSMSAttributes', 614 | method = 'POST', 615 | cred = cred, 616 | content_type = CONTENT_TYPE, 617 | pathname = '/', 618 | body = data or '', 619 | header_keys = SETSMSATTRIBUTES_HEADER_KEYS, 620 | header_data = opts, 621 | }) 622 | end 623 | 624 | 625 | 626 | local ADDPERMISSION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 627 | function _M.AddPermission(self, cred, opts, data) 628 | return request({ 629 | signature_version = SIGNATURE_VERSION, 630 | version = VERSION, 631 | service = self.service, 632 | host = self.host, 633 | scope = self.scope, 634 | action = 'AddPermission', 635 | method = 'POST', 636 | cred = cred, 637 | content_type = CONTENT_TYPE, 638 | pathname = '/', 639 | body = data or '', 640 | header_keys = ADDPERMISSION_HEADER_KEYS, 641 | header_data = opts, 642 | }) 643 | end 644 | 645 | 646 | 647 | local GETTOPICATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 648 | function _M.GetTopicAttributes(self, cred, opts, data) 649 | return request({ 650 | signature_version = SIGNATURE_VERSION, 651 | version = VERSION, 652 | service = self.service, 653 | host = self.host, 654 | scope = self.scope, 655 | action = 'GetTopicAttributes', 656 | method = 'POST', 657 | cred = cred, 658 | content_type = CONTENT_TYPE, 659 | pathname = '/', 660 | body = data or '', 661 | header_keys = GETTOPICATTRIBUTES_HEADER_KEYS, 662 | header_data = opts, 663 | }) 664 | end 665 | 666 | 667 | 668 | local GETPLATFORMAPPLICATIONATTRIBUTES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 669 | function _M.GetPlatformApplicationAttributes(self, cred, opts, data) 670 | return request({ 671 | signature_version = SIGNATURE_VERSION, 672 | version = VERSION, 673 | service = self.service, 674 | host = self.host, 675 | scope = self.scope, 676 | action = 'GetPlatformApplicationAttributes', 677 | method = 'POST', 678 | cred = cred, 679 | content_type = CONTENT_TYPE, 680 | pathname = '/', 681 | body = data or '', 682 | header_keys = GETPLATFORMAPPLICATIONATTRIBUTES_HEADER_KEYS, 683 | header_data = opts, 684 | }) 685 | end 686 | 687 | 688 | 689 | return _M 690 | 691 | 692 | -------------------------------------------------------------------------------- /lib/resty/aws/lambda.lua: -------------------------------------------------------------------------------- 1 | -- 2 | --- @module resty.aws.lambda 3 | 4 | local _M = {} 5 | local http = require 'resty.http' 6 | local request = require 'resty.aws.request' 7 | 8 | local VERSION = '2015-03-31' 9 | local CONTENT_TYPE = 'application/json' 10 | local SIGNATURE_VERSION = 'v4' 11 | 12 | local REGIONS = { 13 | ['ap-southeast-1'] = 'ap-southeast-1', 14 | ['ap-northeast-2'] = 'ap-northeast-2', 15 | ['ap-northeast-1'] = 'ap-northeast-1', 16 | ['us-east-2'] = 'us-east-2', 17 | ['us-west-2'] = 'us-west-2', 18 | ['us-east-1'] = 'us-east-1', 19 | ['ap-southeast-2'] = 'ap-southeast-2', 20 | ['eu-central-1'] = 'eu-central-1', 21 | ['eu-west-1'] = 'eu-west-1', 22 | } 23 | 24 | local ENDPOINTS = { 25 | ['ap-southeast-1'] = 'lambda.ap-southeast-1.amazonaws.com', 26 | ['ap-northeast-2'] = 'lambda.ap-northeast-2.amazonaws.com', 27 | ['ap-northeast-1'] = 'lambda.ap-northeast-1.amazonaws.com', 28 | ['us-east-2'] = 'lambda.us-east-2.amazonaws.com', 29 | ['us-west-2'] = 'lambda.us-west-2.amazonaws.com', 30 | ['us-east-1'] = 'lambda.us-east-1.amazonaws.com', 31 | ['ap-southeast-2'] = 'lambda.ap-southeast-2.amazonaws.com', 32 | ['eu-central-1'] = 'lambda.eu-central-1.amazonaws.com', 33 | ['eu-west-1'] = 'lambda.eu-west-1.amazonaws.com', 34 | } 35 | 36 | local mt = { __index = _M } 37 | 38 | function _M.new(_, region) 39 | local r = string.lower(region or os.getenv('AWS_DEFAULT_REGION')) 40 | 41 | if not r then 42 | return nil, '[lambda] region[' .. region .. '] is not available for this service' 43 | end 44 | 45 | return setmetatable({ 46 | service = 'lambda', 47 | scope = r .. '/lambda/aws4_request', 48 | host = ENDPOINTS[r] 49 | }, mt) 50 | end 51 | 52 | 53 | local CREATEFUNCTION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 54 | function _M.CreateFunction(self, cred, opts, data) 55 | return request({ 56 | signature_version = SIGNATURE_VERSION, 57 | version = VERSION, 58 | service = self.service, 59 | host = self.host, 60 | scope = self.scope, 61 | action = 'CreateFunction', 62 | method = 'POST', 63 | cred = cred, 64 | content_type = CONTENT_TYPE, 65 | pathname = '/2015-03-31/functions', 66 | body = data or '', 67 | header_keys = CREATEFUNCTION_HEADER_KEYS, 68 | header_data = opts, 69 | }) 70 | end 71 | 72 | 73 | 74 | local UPDATEEVENTSOURCEMAPPING_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 75 | function _M.UpdateEventSourceMapping(self, cred, opts, data) 76 | local UUID = opts['UUID'] 77 | if not UUID then 78 | return nil, 'UUID is required' 79 | end 80 | 81 | return request({ 82 | signature_version = SIGNATURE_VERSION, 83 | version = VERSION, 84 | service = self.service, 85 | host = self.host, 86 | scope = self.scope, 87 | action = 'UpdateEventSourceMapping', 88 | method = 'PUT', 89 | cred = cred, 90 | content_type = CONTENT_TYPE, 91 | pathname = '/2015-03-31/event-source-mappings/' .. UUID, 92 | body = data or '', 93 | header_keys = UPDATEEVENTSOURCEMAPPING_HEADER_KEYS, 94 | header_data = opts, 95 | }) 96 | end 97 | 98 | 99 | 100 | local GETALIAS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 101 | function _M.GetAlias(self, cred, opts, data) 102 | local FunctionName = opts['FunctionName'] 103 | if not FunctionName then 104 | return nil, 'FunctionName is required' 105 | end 106 | 107 | local Name = opts['Name'] 108 | if not Name then 109 | return nil, 'Name is required' 110 | end 111 | 112 | return request({ 113 | signature_version = SIGNATURE_VERSION, 114 | version = VERSION, 115 | service = self.service, 116 | host = self.host, 117 | scope = self.scope, 118 | action = 'GetAlias', 119 | method = 'GET', 120 | cred = cred, 121 | content_type = CONTENT_TYPE, 122 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/aliases/' .. Name, 123 | body = data or '', 124 | header_keys = GETALIAS_HEADER_KEYS, 125 | header_data = opts, 126 | }) 127 | end 128 | 129 | 130 | 131 | local LISTEVENTSOURCEMAPPINGS_QUERY_KEYS = { 'EventSourceArn', 'FunctionName', 'Marker', 'MaxItems' } 132 | local LISTEVENTSOURCEMAPPINGS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 133 | function _M.ListEventSourceMappings(self, cred, opts, data) 134 | return request({ 135 | signature_version = SIGNATURE_VERSION, 136 | version = VERSION, 137 | service = self.service, 138 | host = self.host, 139 | scope = self.scope, 140 | action = 'ListEventSourceMappings', 141 | method = 'GET', 142 | cred = cred, 143 | content_type = CONTENT_TYPE, 144 | pathname = '/2015-03-31/event-source-mappings', 145 | body = data or '', 146 | query_keys = LISTEVENTSOURCEMAPPINGS_QUERY_KEYS, 147 | query_data = opts, 148 | header_keys = LISTEVENTSOURCEMAPPINGS_HEADER_KEYS, 149 | header_data = opts, 150 | }) 151 | end 152 | 153 | 154 | 155 | local LISTALIASES_QUERY_KEYS = { 'FunctionVersion', 'Marker', 'MaxItems' } 156 | local LISTALIASES_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 157 | function _M.ListAliases(self, cred, opts, data) 158 | local FunctionName = opts['FunctionName'] 159 | if not FunctionName then 160 | return nil, 'FunctionName is required' 161 | end 162 | 163 | return request({ 164 | signature_version = SIGNATURE_VERSION, 165 | version = VERSION, 166 | service = self.service, 167 | host = self.host, 168 | scope = self.scope, 169 | action = 'ListAliases', 170 | method = 'GET', 171 | cred = cred, 172 | content_type = CONTENT_TYPE, 173 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/aliases', 174 | body = data or '', 175 | query_keys = LISTALIASES_QUERY_KEYS, 176 | query_data = opts, 177 | header_keys = LISTALIASES_HEADER_KEYS, 178 | header_data = opts, 179 | }) 180 | end 181 | 182 | 183 | 184 | local DELETEALIAS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 185 | function _M.DeleteAlias(self, cred, opts, data) 186 | local FunctionName = opts['FunctionName'] 187 | if not FunctionName then 188 | return nil, 'FunctionName is required' 189 | end 190 | 191 | local Name = opts['Name'] 192 | if not Name then 193 | return nil, 'Name is required' 194 | end 195 | 196 | return request({ 197 | signature_version = SIGNATURE_VERSION, 198 | version = VERSION, 199 | service = self.service, 200 | host = self.host, 201 | scope = self.scope, 202 | action = 'DeleteAlias', 203 | method = 'DELETE', 204 | cred = cred, 205 | content_type = CONTENT_TYPE, 206 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/aliases/' .. Name, 207 | body = data or '', 208 | header_keys = DELETEALIAS_HEADER_KEYS, 209 | header_data = opts, 210 | }) 211 | end 212 | 213 | 214 | 215 | local INVOKEASYNC_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 216 | function _M.InvokeAsync(self, cred, opts, data) 217 | local FunctionName = opts['FunctionName'] 218 | if not FunctionName then 219 | return nil, 'FunctionName is required' 220 | end 221 | 222 | return request({ 223 | signature_version = SIGNATURE_VERSION, 224 | version = VERSION, 225 | service = self.service, 226 | host = self.host, 227 | scope = self.scope, 228 | action = 'InvokeAsync', 229 | method = 'POST', 230 | cred = cred, 231 | content_type = CONTENT_TYPE, 232 | pathname = '/2014-11-13/functions/' .. FunctionName .. '/invoke-async', 233 | body = data or '', 234 | header_keys = INVOKEASYNC_HEADER_KEYS, 235 | header_data = opts, 236 | }) 237 | end 238 | 239 | 240 | 241 | local GETPOLICY_QUERY_KEYS = { 'Qualifier' } 242 | local GETPOLICY_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 243 | function _M.GetPolicy(self, cred, opts, data) 244 | local FunctionName = opts['FunctionName'] 245 | if not FunctionName then 246 | return nil, 'FunctionName is required' 247 | end 248 | 249 | return request({ 250 | signature_version = SIGNATURE_VERSION, 251 | version = VERSION, 252 | service = self.service, 253 | host = self.host, 254 | scope = self.scope, 255 | action = 'GetPolicy', 256 | method = 'GET', 257 | cred = cred, 258 | content_type = CONTENT_TYPE, 259 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/policy', 260 | body = data or '', 261 | query_keys = GETPOLICY_QUERY_KEYS, 262 | query_data = opts, 263 | header_keys = GETPOLICY_HEADER_KEYS, 264 | header_data = opts, 265 | }) 266 | end 267 | 268 | 269 | 270 | local DELETEEVENTSOURCEMAPPING_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 271 | function _M.DeleteEventSourceMapping(self, cred, opts, data) 272 | local UUID = opts['UUID'] 273 | if not UUID then 274 | return nil, 'UUID is required' 275 | end 276 | 277 | return request({ 278 | signature_version = SIGNATURE_VERSION, 279 | version = VERSION, 280 | service = self.service, 281 | host = self.host, 282 | scope = self.scope, 283 | action = 'DeleteEventSourceMapping', 284 | method = 'DELETE', 285 | cred = cred, 286 | content_type = CONTENT_TYPE, 287 | pathname = '/2015-03-31/event-source-mappings/' .. UUID, 288 | body = data or '', 289 | header_keys = DELETEEVENTSOURCEMAPPING_HEADER_KEYS, 290 | header_data = opts, 291 | }) 292 | end 293 | 294 | 295 | 296 | local LISTFUNCTIONS_QUERY_KEYS = { 'Marker', 'MaxItems' } 297 | local LISTFUNCTIONS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 298 | function _M.ListFunctions(self, cred, opts, data) 299 | return request({ 300 | signature_version = SIGNATURE_VERSION, 301 | version = VERSION, 302 | service = self.service, 303 | host = self.host, 304 | scope = self.scope, 305 | action = 'ListFunctions', 306 | method = 'GET', 307 | cred = cred, 308 | content_type = CONTENT_TYPE, 309 | pathname = '/2015-03-31/functions', 310 | body = data or '', 311 | query_keys = LISTFUNCTIONS_QUERY_KEYS, 312 | query_data = opts, 313 | header_keys = LISTFUNCTIONS_HEADER_KEYS, 314 | header_data = opts, 315 | }) 316 | end 317 | 318 | 319 | 320 | local CREATEEVENTSOURCEMAPPING_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 321 | function _M.CreateEventSourceMapping(self, cred, opts, data) 322 | return request({ 323 | signature_version = SIGNATURE_VERSION, 324 | version = VERSION, 325 | service = self.service, 326 | host = self.host, 327 | scope = self.scope, 328 | action = 'CreateEventSourceMapping', 329 | method = 'POST', 330 | cred = cred, 331 | content_type = CONTENT_TYPE, 332 | pathname = '/2015-03-31/event-source-mappings', 333 | body = data or '', 334 | header_keys = CREATEEVENTSOURCEMAPPING_HEADER_KEYS, 335 | header_data = opts, 336 | }) 337 | end 338 | 339 | 340 | 341 | local UPDATEFUNCTIONCODE_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 342 | function _M.UpdateFunctionCode(self, cred, opts, data) 343 | local FunctionName = opts['FunctionName'] 344 | if not FunctionName then 345 | return nil, 'FunctionName is required' 346 | end 347 | 348 | return request({ 349 | signature_version = SIGNATURE_VERSION, 350 | version = VERSION, 351 | service = self.service, 352 | host = self.host, 353 | scope = self.scope, 354 | action = 'UpdateFunctionCode', 355 | method = 'PUT', 356 | cred = cred, 357 | content_type = CONTENT_TYPE, 358 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/code', 359 | body = data or '', 360 | header_keys = UPDATEFUNCTIONCODE_HEADER_KEYS, 361 | header_data = opts, 362 | }) 363 | end 364 | 365 | 366 | 367 | local GETFUNCTION_QUERY_KEYS = { 'Qualifier' } 368 | local GETFUNCTION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 369 | function _M.GetFunction(self, cred, opts, data) 370 | local FunctionName = opts['FunctionName'] 371 | if not FunctionName then 372 | return nil, 'FunctionName is required' 373 | end 374 | 375 | return request({ 376 | signature_version = SIGNATURE_VERSION, 377 | version = VERSION, 378 | service = self.service, 379 | host = self.host, 380 | scope = self.scope, 381 | action = 'GetFunction', 382 | method = 'GET', 383 | cred = cred, 384 | content_type = CONTENT_TYPE, 385 | pathname = '/2015-03-31/functions/' .. FunctionName, 386 | body = data or '', 387 | query_keys = GETFUNCTION_QUERY_KEYS, 388 | query_data = opts, 389 | header_keys = GETFUNCTION_HEADER_KEYS, 390 | header_data = opts, 391 | }) 392 | end 393 | 394 | 395 | 396 | local DELETEFUNCTION_QUERY_KEYS = { 'Qualifier' } 397 | local DELETEFUNCTION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 398 | function _M.DeleteFunction(self, cred, opts, data) 399 | local FunctionName = opts['FunctionName'] 400 | if not FunctionName then 401 | return nil, 'FunctionName is required' 402 | end 403 | 404 | return request({ 405 | signature_version = SIGNATURE_VERSION, 406 | version = VERSION, 407 | service = self.service, 408 | host = self.host, 409 | scope = self.scope, 410 | action = 'DeleteFunction', 411 | method = 'DELETE', 412 | cred = cred, 413 | content_type = CONTENT_TYPE, 414 | pathname = '/2015-03-31/functions/' .. FunctionName, 415 | body = data or '', 416 | query_keys = DELETEFUNCTION_QUERY_KEYS, 417 | query_data = opts, 418 | header_keys = DELETEFUNCTION_HEADER_KEYS, 419 | header_data = opts, 420 | }) 421 | end 422 | 423 | 424 | 425 | local GETEVENTSOURCEMAPPING_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 426 | function _M.GetEventSourceMapping(self, cred, opts, data) 427 | local UUID = opts['UUID'] 428 | if not UUID then 429 | return nil, 'UUID is required' 430 | end 431 | 432 | return request({ 433 | signature_version = SIGNATURE_VERSION, 434 | version = VERSION, 435 | service = self.service, 436 | host = self.host, 437 | scope = self.scope, 438 | action = 'GetEventSourceMapping', 439 | method = 'GET', 440 | cred = cred, 441 | content_type = CONTENT_TYPE, 442 | pathname = '/2015-03-31/event-source-mappings/' .. UUID, 443 | body = data or '', 444 | header_keys = GETEVENTSOURCEMAPPING_HEADER_KEYS, 445 | header_data = opts, 446 | }) 447 | end 448 | 449 | 450 | 451 | local UPDATEALIAS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 452 | function _M.UpdateAlias(self, cred, opts, data) 453 | local FunctionName = opts['FunctionName'] 454 | if not FunctionName then 455 | return nil, 'FunctionName is required' 456 | end 457 | 458 | local Name = opts['Name'] 459 | if not Name then 460 | return nil, 'Name is required' 461 | end 462 | 463 | return request({ 464 | signature_version = SIGNATURE_VERSION, 465 | version = VERSION, 466 | service = self.service, 467 | host = self.host, 468 | scope = self.scope, 469 | action = 'UpdateAlias', 470 | method = 'PUT', 471 | cred = cred, 472 | content_type = CONTENT_TYPE, 473 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/aliases/' .. Name, 474 | body = data or '', 475 | header_keys = UPDATEALIAS_HEADER_KEYS, 476 | header_data = opts, 477 | }) 478 | end 479 | 480 | 481 | 482 | local CREATEALIAS_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 483 | function _M.CreateAlias(self, cred, opts, data) 484 | local FunctionName = opts['FunctionName'] 485 | if not FunctionName then 486 | return nil, 'FunctionName is required' 487 | end 488 | 489 | return request({ 490 | signature_version = SIGNATURE_VERSION, 491 | version = VERSION, 492 | service = self.service, 493 | host = self.host, 494 | scope = self.scope, 495 | action = 'CreateAlias', 496 | method = 'POST', 497 | cred = cred, 498 | content_type = CONTENT_TYPE, 499 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/aliases', 500 | body = data or '', 501 | header_keys = CREATEALIAS_HEADER_KEYS, 502 | header_data = opts, 503 | }) 504 | end 505 | 506 | 507 | 508 | local PUBLISHVERSION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 509 | function _M.PublishVersion(self, cred, opts, data) 510 | local FunctionName = opts['FunctionName'] 511 | if not FunctionName then 512 | return nil, 'FunctionName is required' 513 | end 514 | 515 | return request({ 516 | signature_version = SIGNATURE_VERSION, 517 | version = VERSION, 518 | service = self.service, 519 | host = self.host, 520 | scope = self.scope, 521 | action = 'PublishVersion', 522 | method = 'POST', 523 | cred = cred, 524 | content_type = CONTENT_TYPE, 525 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/versions', 526 | body = data or '', 527 | header_keys = PUBLISHVERSION_HEADER_KEYS, 528 | header_data = opts, 529 | }) 530 | end 531 | 532 | 533 | 534 | local REMOVEPERMISSION_QUERY_KEYS = { 'Qualifier' } 535 | local REMOVEPERMISSION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 536 | function _M.RemovePermission(self, cred, opts, data) 537 | local FunctionName = opts['FunctionName'] 538 | if not FunctionName then 539 | return nil, 'FunctionName is required' 540 | end 541 | 542 | local StatementId = opts['StatementId'] 543 | if not StatementId then 544 | return nil, 'StatementId is required' 545 | end 546 | 547 | return request({ 548 | signature_version = SIGNATURE_VERSION, 549 | version = VERSION, 550 | service = self.service, 551 | host = self.host, 552 | scope = self.scope, 553 | action = 'RemovePermission', 554 | method = 'DELETE', 555 | cred = cred, 556 | content_type = CONTENT_TYPE, 557 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/policy/' .. StatementId, 558 | body = data or '', 559 | query_keys = REMOVEPERMISSION_QUERY_KEYS, 560 | query_data = opts, 561 | header_keys = REMOVEPERMISSION_HEADER_KEYS, 562 | header_data = opts, 563 | }) 564 | end 565 | 566 | 567 | 568 | local LISTVERSIONSBYFUNCTION_QUERY_KEYS = { 'Marker', 'MaxItems' } 569 | local LISTVERSIONSBYFUNCTION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 570 | function _M.ListVersionsByFunction(self, cred, opts, data) 571 | local FunctionName = opts['FunctionName'] 572 | if not FunctionName then 573 | return nil, 'FunctionName is required' 574 | end 575 | 576 | return request({ 577 | signature_version = SIGNATURE_VERSION, 578 | version = VERSION, 579 | service = self.service, 580 | host = self.host, 581 | scope = self.scope, 582 | action = 'ListVersionsByFunction', 583 | method = 'GET', 584 | cred = cred, 585 | content_type = CONTENT_TYPE, 586 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/versions', 587 | body = data or '', 588 | query_keys = LISTVERSIONSBYFUNCTION_QUERY_KEYS, 589 | query_data = opts, 590 | header_keys = LISTVERSIONSBYFUNCTION_HEADER_KEYS, 591 | header_data = opts, 592 | }) 593 | end 594 | 595 | 596 | 597 | local UPDATEFUNCTIONCONFIGURATION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 598 | function _M.UpdateFunctionConfiguration(self, cred, opts, data) 599 | local FunctionName = opts['FunctionName'] 600 | if not FunctionName then 601 | return nil, 'FunctionName is required' 602 | end 603 | 604 | return request({ 605 | signature_version = SIGNATURE_VERSION, 606 | version = VERSION, 607 | service = self.service, 608 | host = self.host, 609 | scope = self.scope, 610 | action = 'UpdateFunctionConfiguration', 611 | method = 'PUT', 612 | cred = cred, 613 | content_type = CONTENT_TYPE, 614 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/configuration', 615 | body = data or '', 616 | header_keys = UPDATEFUNCTIONCONFIGURATION_HEADER_KEYS, 617 | header_data = opts, 618 | }) 619 | end 620 | 621 | 622 | 623 | local ADDPERMISSION_QUERY_KEYS = { 'Qualifier' } 624 | local ADDPERMISSION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 625 | function _M.AddPermission(self, cred, opts, data) 626 | local FunctionName = opts['FunctionName'] 627 | if not FunctionName then 628 | return nil, 'FunctionName is required' 629 | end 630 | 631 | return request({ 632 | signature_version = SIGNATURE_VERSION, 633 | version = VERSION, 634 | service = self.service, 635 | host = self.host, 636 | scope = self.scope, 637 | action = 'AddPermission', 638 | method = 'POST', 639 | cred = cred, 640 | content_type = CONTENT_TYPE, 641 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/policy', 642 | body = data or '', 643 | query_keys = ADDPERMISSION_QUERY_KEYS, 644 | query_data = opts, 645 | header_keys = ADDPERMISSION_HEADER_KEYS, 646 | header_data = opts, 647 | }) 648 | end 649 | 650 | 651 | 652 | local GETFUNCTIONCONFIGURATION_QUERY_KEYS = { 'Qualifier' } 653 | local GETFUNCTIONCONFIGURATION_HEADER_KEYS = { 'Host', 'X-Amz-Date', 'X-Amz-Security-Token' } 654 | function _M.GetFunctionConfiguration(self, cred, opts, data) 655 | local FunctionName = opts['FunctionName'] 656 | if not FunctionName then 657 | return nil, 'FunctionName is required' 658 | end 659 | 660 | return request({ 661 | signature_version = SIGNATURE_VERSION, 662 | version = VERSION, 663 | service = self.service, 664 | host = self.host, 665 | scope = self.scope, 666 | action = 'GetFunctionConfiguration', 667 | method = 'GET', 668 | cred = cred, 669 | content_type = CONTENT_TYPE, 670 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/configuration', 671 | body = data or '', 672 | query_keys = GETFUNCTIONCONFIGURATION_QUERY_KEYS, 673 | query_data = opts, 674 | header_keys = GETFUNCTIONCONFIGURATION_HEADER_KEYS, 675 | header_data = opts, 676 | }) 677 | end 678 | 679 | 680 | 681 | local INVOKE_QUERY_KEYS = { 'Qualifier' } 682 | local INVOKE_HEADER_KEYS = { 'Host', 'X-Amz-Client-Context', 'X-Amz-Date', 'X-Amz-Invocation-Type', 'X-Amz-Log-Type', 'X-Amz-Security-Token' } 683 | function _M.Invoke(self, cred, opts, data) 684 | local FunctionName = opts['FunctionName'] 685 | if not FunctionName then 686 | return nil, 'FunctionName is required' 687 | end 688 | 689 | return request({ 690 | signature_version = SIGNATURE_VERSION, 691 | version = VERSION, 692 | service = self.service, 693 | host = self.host, 694 | scope = self.scope, 695 | action = 'Invoke', 696 | method = 'POST', 697 | cred = cred, 698 | content_type = CONTENT_TYPE, 699 | pathname = '/2015-03-31/functions/' .. FunctionName .. '/invocations', 700 | body = data or '', 701 | query_keys = INVOKE_QUERY_KEYS, 702 | query_data = opts, 703 | header_keys = INVOKE_HEADER_KEYS, 704 | header_data = opts, 705 | }) 706 | end 707 | 708 | 709 | 710 | return _M 711 | 712 | 713 | --------------------------------------------------------------------------------