Closed CriztianiX closed 10 years ago
hi, sorry for late reply, but thank you for trying to use lua-aws, also many improvement in your repo!! I checked my code and I think this is because my v2 encoding code contains some easy mistake. I made fix and confirmed that createQueue action is worked with parameter QueueName.
but with sendMessage/deleteQueue action, I encountered strange 403, Signature not matched error. I still keep on investigating problem. but I will provide diff (based on your master) for the first time.
diff --git a/lua-aws/api.lua b/lua-aws/api.lua
index b23130b..ea5d5c4 100644
--- a/lua-aws/api.lua
+++ b/lua-aws/api.lua
@@ -4,8 +4,10 @@ local Request = require ('lua-aws.request')
local p
do
- local _obj_0 = require("moon")
- p = _obj_0.p
+ local ok, _obj_0 = pcall(require, "moon")
+ if ok then
+ p = _obj_0.p
+ end
end
local get_endpoint_from_env = function ()
diff --git a/lua-aws/core.lua b/lua-aws/core.lua
index 86def98..148551b 100644
--- a/lua-aws/core.lua
+++ b/lua-aws/core.lua
@@ -10,7 +10,7 @@ local AWS = class.AWS {
--> define service
self.DynamoDB = require('lua-aws.services.dynamodb').new(self)
self.EC2 = require('lua-aws.services.ec2').new(self)
- self.SQS = require('lua-aws.services.sqs').new(self)
+ self.SQS = require('lua-aws.services.sqs').new(self)
--[[
require('./services/autoscaling')
diff --git a/lua-aws/requests/base.lua b/lua-aws/requests/base.lua
index 187002b..ac85d06 100644
--- a/lua-aws/requests/base.lua
+++ b/lua-aws/requests/base.lua
@@ -6,8 +6,10 @@ local EndPoint = require ('lua-aws.requests.endpoint')
local p
do
- local _obj_0 = require("moon")
- p = _obj_0.p
+ local ok, _obj_0 = pcall(require, "moon")
+ if ok then
+ p = _obj_0.p
+ end
end
return class.AWS_Request {
@@ -15,20 +17,21 @@ return class.AWS_Request {
self._operation = operation
self._params = params or {}
self._api = api
- s_version = api:signature_version()
+ local s_version = api:signature_version()
+ assert(Signer[s_version], "signer not implement:"..s_version)
self._signer = Signer[s_version].new()
end,
send = function (self)
local req = self:base_build_request()
self:build_request(req)
self:validate(req)
- _api_timestamp = self._api:timestamp()
+ local _api_timestamp = self._api:timestamp()
self._signer:sign(req, self._api:config(), _api_timestamp)
local resp = self._api:http_request(req)
if resp.status == 200 then
return self:extract_data(resp)
else
- print("Something wrong in the request")
+ self._api:log("Something wrong in the request", resp.status, resp.body)
return self:extract_error(resp)
end
end,
@@ -96,7 +99,7 @@ return class.AWS_Request {
message = string,
}
]]--
- extract_data = function (self, resp)
+ extract_error = function (self, resp)
assert(false)
end,
}
diff --git a/lua-aws/requests/query.lua b/lua-aws/requests/query.lua
index db23036..defeb0b 100644
--- a/lua-aws/requests/query.lua
+++ b/lua-aws/requests/query.lua
@@ -9,7 +9,7 @@ return class.AWS_QueryRequest.extends(Request) {
if rules then
rules = rules.members
end
- local builder = Serializer.new(rules, self._api)
+ local builder = Serializer.new(self._api, rules)
builder:serialize(self._params, function(name, value)
params[name] = value
end)
diff --git a/lua-aws/requests/query_string_serializer.lua b/lua-aws/requests/query_string_serializer.lua
index 74320b5..b916ab1 100644
--- a/lua-aws/requests/query_string_serializer.lua
+++ b/lua-aws/requests/query_string_serializer.lua
@@ -8,7 +8,7 @@ return class.AWS_RequestSerializer {
end,
serialize = function (self, params, fn)
- self:serialize_struct('', params, self._rules, fn)
+ self:serialize_struct(false, params, self._rules, fn)
end,
serialize_struct = function (self, prefix, struct, rules, fn)
@@ -59,9 +59,9 @@ return class.AWS_RequestSerializer {
self:serialize_map(name, value, rules, fn)
elseif rules.type == 'timestamp' then
local timestamp_format = (rules.format or self._api:timestamp_format())
- fn.call(self, name, util.date_format(value, timestamp_format))
+ fn(name, util.date_format(value, timestamp_format))
else
- fn.call(self, name, tostring(value))
+ fn(name, tostring(value))
end
end,
}
diff --git a/lua-aws/util.lua b/lua-aws/util.lua
index ee1d15e..6c40630 100644
--- a/lua-aws/util.lua
+++ b/lua-aws/util.lua
@@ -432,6 +432,7 @@ local fill_header = function (req)
req.headers["Connection"] = "Keep-Alive"
end
local http_print = function (...)
+ -- print(...)
end
if luasocket_ok then
local ltn12 = require"ltn12"
@@ -445,6 +446,7 @@ if luasocket_ok then
source = ltn12.source.string(req.body),
sink = ltn12.sink.table(respbody)
}
+ http_print('requestto:', req.protocol .. "://" .. req.host .. ":" .. req.port .. req.path)
http_print('sentbody:', req.body)
http_print('result of query:', result, respcode, respstatus)
for k,v in pairs(respheaders) do
diff --git a/test/sqs.lua b/test/sqs.lua
new file mode 100644
index 0000000..f127b3f
--- /dev/null
+++ b/test/sqs.lua
@@ -0,0 +1,35 @@
+local AWS = require ('lua-aws.init')
+local aws = AWS.new({
+ accessKeyId = os.getenv('AWS_ACCESS_KEY'),
+ secretAccessKey = os.getenv('AWS_SECRET_KEY')
+})
+
+local function dump_res(tag, res)
+ for k,v in pairs(res) do
+ print(tag, k, v)
+ if type(v) == 'table' then
+ for kk,vv in pairs(v) do
+ print(tag, k, kk, vv)
+ end
+ end
+ end
+end
+
+local res
+res = aws.SQS:api_by_version('2012-11-05'):createQueue({
+ QueueName = "testQueue",
+})
+dump_res('create', res)
+
+local params = {
+ QueueUrl = "https://sqs.ap-northeast-1.amazonaws.com/871570535967/testQueue",
+ MessageBody = "testing"
+}
+res = aws.SQS:api_by_version('2012-11-05'):sendMessage(params)
+dump_res('message', res)
+
+
+res = aws.SQS:api_by_version('2012-11-05'):deleteQueue({
+ QueueUrl = "https://sqs.ap-northeast-1.amazonaws.com/871570535967/testQueue",
+})
+dump_res('delete', res)
diff --git a/lua-aws/api.lua b/lua-aws/api.lua
index b23130b..ea5d5c4 100644
--- a/lua-aws/api.lua
+++ b/lua-aws/api.lua
@@ -4,8 +4,10 @@ local Request = require ('lua-aws.request')
local p
do
- local _obj_0 = require("moon")
- p = _obj_0.p
+ local ok, _obj_0 = pcall(require, "moon")
+ if ok then
+ p = _obj_0.p
+ end
end
local get_endpoint_from_env = function ()
diff --git a/lua-aws/core.lua b/lua-aws/core.lua
index 86def98..148551b 100644
--- a/lua-aws/core.lua
+++ b/lua-aws/core.lua
@@ -10,7 +10,7 @@ local AWS = class.AWS {
--> define service
self.DynamoDB = require('lua-aws.services.dynamodb').new(self)
self.EC2 = require('lua-aws.services.ec2').new(self)
- self.SQS = require('lua-aws.services.sqs').new(self)
+ self.SQS = require('lua-aws.services.sqs').new(self)
--[[
require('./services/autoscaling')
diff --git a/lua-aws/requests/base.lua b/lua-aws/requests/base.lua
index 187002b..ac85d06 100644
--- a/lua-aws/requests/base.lua
+++ b/lua-aws/requests/base.lua
@@ -6,8 +6,10 @@ local EndPoint = require ('lua-aws.requests.endpoint')
local p
do
- local _obj_0 = require("moon")
- p = _obj_0.p
+ local ok, _obj_0 = pcall(require, "moon")
+ if ok then
+ p = _obj_0.p
+ end
end
return class.AWS_Request {
@@ -15,20 +17,21 @@ return class.AWS_Request {
self._operation = operation
self._params = params or {}
self._api = api
- s_version = api:signature_version()
+ local s_version = api:signature_version()
+ assert(Signer[s_version], "signer not implement:"..s_version)
self._signer = Signer[s_version].new()
end,
send = function (self)
local req = self:base_build_request()
self:build_request(req)
self:validate(req)
- _api_timestamp = self._api:timestamp()
+ local _api_timestamp = self._api:timestamp()
self._signer:sign(req, self._api:config(), _api_timestamp)
local resp = self._api:http_request(req)
if resp.status == 200 then
return self:extract_data(resp)
else
- print("Something wrong in the request")
+ self._api:log("Something wrong in the request", resp.status, resp.body)
return self:extract_error(resp)
end
end,
@@ -96,7 +99,7 @@ return class.AWS_Request {
message = string,
}
]]--
- extract_data = function (self, resp)
+ extract_error = function (self, resp)
assert(false)
end,
}
diff --git a/lua-aws/requests/query.lua b/lua-aws/requests/query.lua
index db23036..defeb0b 100644
--- a/lua-aws/requests/query.lua
+++ b/lua-aws/requests/query.lua
@@ -9,7 +9,7 @@ return class.AWS_QueryRequest.extends(Request) {
if rules then
rules = rules.members
end
- local builder = Serializer.new(rules, self._api)
+ local builder = Serializer.new(self._api, rules)
builder:serialize(self._params, function(name, value)
params[name] = value
end)
diff --git a/lua-aws/requests/query_string_serializer.lua b/lua-aws/requests/query_string_serializer.lua
index 74320b5..b916ab1 100644
--- a/lua-aws/requests/query_string_serializer.lua
+++ b/lua-aws/requests/query_string_serializer.lua
@@ -8,7 +8,7 @@ return class.AWS_RequestSerializer {
end,
serialize = function (self, params, fn)
- self:serialize_struct('', params, self._rules, fn)
+ self:serialize_struct(false, params, self._rules, fn)
end,
serialize_struct = function (self, prefix, struct, rules, fn)
@@ -59,9 +59,9 @@ return class.AWS_RequestSerializer {
self:serialize_map(name, value, rules, fn)
elseif rules.type == 'timestamp' then
local timestamp_format = (rules.format or self._api:timestamp_format())
- fn.call(self, name, util.date_format(value, timestamp_format))
+ fn(name, util.date_format(value, timestamp_format))
else
- fn.call(self, name, tostring(value))
+ fn(name, tostring(value))
end
end,
}
diff --git a/lua-aws/util.lua b/lua-aws/util.lua
index ee1d15e..6c40630 100644
--- a/lua-aws/util.lua
+++ b/lua-aws/util.lua
@@ -432,6 +432,7 @@ local fill_header = function (req)
req.headers["Connection"] = "Keep-Alive"
end
local http_print = function (...)
+ -- print(...)
end
if luasocket_ok then
local ltn12 = require"ltn12"
@@ -445,6 +446,7 @@ if luasocket_ok then
source = ltn12.source.string(req.body),
sink = ltn12.sink.table(respbody)
}
+ http_print('requestto:', req.protocol .. "://" .. req.host .. ":" .. req.port .. req.path)
http_print('sentbody:', req.body)
http_print('result of query:', result, respcode, respstatus)
for k,v in pairs(respheaders) do
diff --git a/test/sqs.lua b/test/sqs.lua
new file mode 100644
index 0000000..f6c180f
--- /dev/null
+++ b/test/sqs.lua
@@ -0,0 +1,37 @@
+local AWS = require ('lua-aws.init')
+local aws = AWS.new({
+ accessKeyId = os.getenv('AWS_ACCESS_KEY'),
+ secretAccessKey = os.getenv('AWS_SECRET_KEY')
+})
+
+local function dump_res(tag, res)
+ for k,v in pairs(res) do
+ print(tag, k, v)
+ if type(v) == 'table' then
+ for kk,vv in pairs(v) do
+ print(tag, k, kk, vv)
+ end
+ end
+ end
+end
+
+local res
+res = aws.SQS:api_by_version('2012-11-05'):createQueue({
+ QueueName = "testQueue",
+})
+dump_res('create', res)
+
+--[[
+local params = {
+ QueueUrl = "https://sqs.$region.amazonaws.com/$id/$queueName",
+ MessageBody = "testing"
+}
+res = aws.SQS:api_by_version('2012-11-05'):sendMessage(params)
+dump_res('message', res)
+
+
+res = aws.SQS:api_by_version('2012-11-05'):deleteQueue({
+ QueueUrl = "https://sqs.$region.amazonaws.com/$id/$queueName",
+})
+dump_res('delete', res)
+]]
\ No newline at end of file
oh thanks! I will apply this patch for testing!
Yes.. With the patch applied i get a lot of errors with signature checks!
qs:v[2012-11-05]: Something wrong in the request 403 <?xml version="1.0"?>SignatureDoesNotMatch
SignatureDoesNotMatch
SignatureDoesNotMatch
hi, thank you for testing. finally, it is because current URL escape code wrongly escapse "." character. (and QueueUrl likely to contain "." character). after fix it, sendMessage/deleteQueue also works. here is another diff from previous patch.
btw, with my investigation, QueueUrl format is https://sqs.$region.amazonaws.com/$id/$queueName but your example's QueueUrl has the value like QueueUrl = "DEV_email-one2one" it is just hiding actual url, that is ok. but if not, please review your actual Queue URL. thanks!
diff --git a/lua-aws/util.lua b/lua-aws/util.lua
index 6c40630..f3a52cc 100644
--- a/lua-aws/util.lua
+++ b/lua-aws/util.lua
@@ -323,7 +323,7 @@ end
-- taken from Lua Socket and added underscore to ignore (MIT-License)
-----------------------------------------------------------------------------
function _M.escape(s)
- return string.gsub(s, "([^A-Za-z0-9_%-])", function(c)
+ return string.gsub(s, "([^A-Za-z0-9_%-%.])", function(c)
return string.format("%%%02X", string.byte(c))
end)
end
@@ -337,8 +337,8 @@ end
-- taken from Lua Socket
-----------------------------------------------------------------------------
function _M.unescape(s)
- return string.gsub(s, "%%(%X%X)", function(hex)
- return string.char(base.tonumber(hex, 16))
+ return string.gsub(s, "%%(%x%x)", function(hex)
+ return string.char(tonumber(hex, 16))
end)
end
diff --git a/test/signer/v2.lua b/test/signer/v2.lua
new file mode 100644
index 0000000..ec360b8
--- /dev/null
+++ b/test/signer/v2.lua
@@ -0,0 +1,39 @@
+--[[
+AWSAccessKeyId=$AWS_ACCESS_KEY&
+Action=SendMessage&
+MessageBody=testing&
+QueueUrl=http%3A%2F%2Fsqs.ap-northeast-1.amazonaws.com%2F871570535967%2FtestQueue&
+Signature=hchgVw%2B5D5vwSSCgMVsOt5ycJjb6bDOpNmCe4EpLavo%3D&
+SignatureMethod=HmacSHA256&
+SignatureVersion=2&
+Timestamp=2014-10-06T03%3A46%3A55.305Z&
+Version=2012-11-05
+]]--
+
+local v2signer = require 'lua-aws.signers.v2'
+local endpoint = require 'lua-aws.requests.endpoint'
+local util = require 'lua-aws.util'
+
+local signer = v2signer.new()
+
+local params = {
+ Action = "SendMessage",
+ QueueUrl = "http://sqs.ap-northeast-1.amazonaws.com/871570535967/testQueue",
+ MessageBody = "testing",
+ Version = "2012-11-05"
+}
+
+signer:sign({
+ method = "POST",
+ headers = {},
+ host = "sqs.ap-northeast-1.amazonaws.com",
+ path = "/",
+ params = params,
+}, {
+ accessKeyId = os.getenv('AWS_ACCESS_KEY'),
+ secretAccessKey = os.getenv('AWS_SECRET_KEY'),
+}, "2014-10-06T03:46:55.305Z")
+
+-- TODO : can we provide universal test??? now its only for *ME*
+print('params:', params.Signature, util.unescape("hchgVw%2B5D5vwSSCgMVsOt5ycJjb6bDOpNmCe4EpLavo%3D"))
+assert(params.Signature == util.unescape("hchgVw%2B5D5vwSSCgMVsOt5ycJjb6bDOpNmCe4EpLavo%3D"))
diff --git a/test/sqs.lua b/test/sqs.lua
index f6c180f..9aab358 100644
--- a/test/sqs.lua
+++ b/test/sqs.lua
@@ -8,9 +8,7 @@ local function dump_res(tag, res)
for k,v in pairs(res) do
print(tag, k, v)
if type(v) == 'table' then
- for kk,vv in pairs(v) do
- print(tag, k, kk, vv)
- end
+ dump_res(tag.."."..k, v)
end
end
end
@@ -21,9 +19,10 @@ res = aws.SQS:api_by_version('2012-11-05'):createQueue({
})
dump_res('create', res)
---[[
+local QueueUrl = res.value.CreateQueueResponse.value.CreateQueueResult.value.QueueUrl.value
+print("QueueUrl:", QueueUrl)
local params = {
- QueueUrl = "https://sqs.$region.amazonaws.com/$id/$queueName",
+ QueueUrl = QueueUrl,
MessageBody = "testing"
}
res = aws.SQS:api_by_version('2012-11-05'):sendMessage(params)
@@ -31,7 +30,7 @@ dump_res('message', res)
res = aws.SQS:api_by_version('2012-11-05'):deleteQueue({
- QueueUrl = "https://sqs.$region.amazonaws.com/$id/$queueName",
+ QueueUrl = QueueUrl,
})
dump_res('delete', res)
-]]
\ No newline at end of file
+-- ]]
\ No newline at end of file
Yes!!I It works! Only i have this issue...
When i configure AWS with
AWS = AWS.new({ accessKeyId = 'AAA', secretAccessKey = 'BBB' })
i get sqs:v[2012-11-05]: sendMessage:error:/usr/lib64/lua/5.1/lua-aws/api.lua:45: attempt to concatenate local 'endpoint' (a nil value)
So... i have to do AWS = AWS.new({ accessKeyId = 'AAA', secretAccessKey = 'BBB', endpoint = "us-east-1.amazonaws.com" })
hi, I think it is most likely to occur when environment value EC2_URL is not set or unset as following. if you don't set EC2_URL env value, you should specify your ec2-url explicitly with constructor param for AWS object.
dokyougemusu-no-MacBook-Pro:lua-aws iyatomi$ unset EC2_URL
dokyougemusu-no-MacBook-Pro:lua-aws iyatomi$ echo $EC2_URL
dokyougemusu-no-MacBook-Pro:lua-aws iyatomi$ luajit test/sqs.lua
sqs:v[2012-11-05]: createQueue:error:./lua-aws/api.lua:53: attempt to concatenate local 'endpoint' (a nil value)
but I agree that more informative message is needed for this situation, so fix little bit.
diff --git a/lua-aws/api.lua b/lua-aws/api.lua
index ea5d5c4..8fce5a4 100644
--- a/lua-aws/api.lua
+++ b/lua-aws/api.lua
@@ -13,7 +13,7 @@ end
local get_endpoint_from_env = function ()
local ec2url = os.getenv('EC2_URL')
if not ec2url then
- return nil
+ error('neither config.endpoint given nor EC2_URL environment set.')
else
return ec2url:gsub('https://ec2%.', '')
end
@@ -21,7 +21,7 @@ end
local get_region_from_env = function ()
local ec2url = os.getenv('EC2_URL')
if not ec2url then
- return nil
+ error('neither config.endpoint given nor EC2_URL environment set.')
else
local region = false
ec2url:gsub('https://ec2%.(.*)%.amazonaws.com.*', function (s)
also, more document is required but sorry for my laziness :<
if it is ok, can you open pull request to my repository?
thank you. now it is merged to main branch.
with #2
When i try to send params for the request...
params = { QueueUrl = "DEV_email-one2one", MessageBody = "testing" }
res = AWS.SQS:api_by_version('2012-11-05'):sendMessage(params)
criztianix@blacker:~$ lua test-aws.lua
sqs:v[2012-11-05]: sendMessage:error:/usr/lib64/lua/5.1/lua-aws/class.lua:34: no such method: QueueUrl stack traceback: /usr/lib64/lua/5.1/lua-aws/class.lua:34: in function </usr/lib64/lua/5.1/lua-aws/class.lua:31> ...lua/5.1/lua-aws/requests/query_string_serializer.lua:16: in function 'serialize_struct' ...lua/5.1/lua-aws/requests/query_string_serializer.lua:11: in function 'serialize' /usr/lib64/lua/5.1/lua-aws/requests/query.lua:13: in function 'serialize_query' /usr/lib64/lua/5.1/lua-aws/requests/query.lua:27: in function 'build_request' /usr/lib64/lua/5.1/lua-aws/requests/base.lua:23: in function </usr/lib64/lua/5.1/lua-aws/requests/base.lua:21> (tail call): ? C: in function 'pcall' /usr/lib64/lua/5.1/lua-aws/api.lua:79: in function 'sendMessage' test-aws.lua:19: in main chunk