diff --git a/src/resty/aws/init.lua b/src/resty/aws/init.lua index 266b737..7a33f5c 100644 --- a/src/resty/aws/init.lua +++ b/src/resty/aws/init.lua @@ -279,12 +279,13 @@ local function s3_patch(request, bucket) end request.host = bucket .. "." .. request.host + request.headers['Host'] = request.host local path = request.path if bucket and path then path = path:sub(#bucket + 2) - if path == "/" then - path = "" + if path == "" then + path = "/" end request.path = path @@ -307,9 +308,11 @@ local function generate_service_methods(service) --print(require("pl.pretty").write(self.config)) -- validate parameters - local ok, err = validate_input(params, operation.input, "params") - if not ok then - return nil, operation_prefix .. " validation error: " .. tostring(err) + if operation.input then + local ok, err = validate_input(params, operation.input, "params") + if not ok then + return nil, operation_prefix .. " validation error: " .. tostring(err) + end end -- generate request data and format it according to the protocol @@ -354,8 +357,18 @@ local function generate_service_methods(service) --print(require("pl.pretty").write(signed_request)) + local need_raw_reader = false + if operation.output then + for key, shape in pairs(operation.output.members) do + if shape.type == 'blob' or shape.streaming then + need_raw_reader = true + break + end + end + end + -- execute the request - local response, err = execute_request(signed_request) + local response, err = execute_request(signed_request, need_raw_reader) if not response then return nil, operation_prefix .. " " .. tostring(err) end diff --git a/src/resty/aws/request/build.lua b/src/resty/aws/request/build.lua index e4b2458..24d5966 100644 --- a/src/resty/aws/request/build.lua +++ b/src/resty/aws/request/build.lua @@ -157,45 +157,47 @@ local function build_request(operation, config, params) -- inject parameters in the right places; path/query/header/body -- this assumes they all live on the top-level of the structure, is this correct?? - for name, member_config in pairs(operation.input.members) do - local param_value = params[name] - -- TODO: date-time value should be properly formatted??? - if param_value ~= nil then - - -- a parameter value is provided - local location = member_config.location - local locationName = member_config.locationName - -- print(name," = ", param_value, ": ",location, " (", locationName,")") - - if location == "uri" then - local place_holder = "{" .. locationName .. "%+?}" - local replacement = escape_uri(param_value):gsub("%%", "%%%%") - request.path = request.path:gsub(place_holder, replacement) - - elseif location == "querystring" then - request.query[locationName] = param_value - - elseif location == "header" then - request.headers[locationName] = param_value - - elseif location == "headers" then - for k,v in pairs(param_value) do - request.headers[locationName .. k] = v - end + if operation.input then + for name, member_config in pairs(operation.input.members) do + local param_value = params[name] + -- TODO: date-time value should be properly formatted??? + if param_value ~= nil then + + -- a parameter value is provided + local location = member_config.location + local locationName = member_config.locationName + -- print(name," = ", param_value, ": ",location, " (", locationName,")") + + if location == "uri" then + local place_holder = "{" .. locationName .. "%+?}" + local replacement = escape_uri(param_value):gsub("%%", "%%%%") + request.path = request.path:gsub(place_holder, replacement) + + elseif location == "querystring" then + request.query[locationName] = param_value + + elseif location == "header" then + request.headers[locationName] = param_value + + elseif location == "headers" then + for k,v in pairs(param_value) do + request.headers[locationName .. k] = v + end + + elseif location == nil then + if config.protocol == "query" then + -- no location specified, but protocol is query, so it goes into query + request.query[name] = param_value + elseif member_config.type == "blob" then + request.body = param_value + else + -- nowhere else to go, so put it in the body (for json and xml) + body_tbl[name] = param_value + end - elseif location == nil then - if config.protocol == "query" then - -- no location specified, but protocol is query, so it goes into query - request.query[name] = param_value - elseif member_config.type == "blob" then - request.body = param_value else - -- nowhere else to go, so put it in the body (for json and xml) - body_tbl[name] = param_value + error("Unknown location: " .. location) end - - else - error("Unknown location: " .. location) end end end diff --git a/src/resty/aws/request/execute.lua b/src/resty/aws/request/execute.lua index 09e43ac..d1da9a3 100644 --- a/src/resty/aws/request/execute.lua +++ b/src/resty/aws/request/execute.lua @@ -12,7 +12,7 @@ local json_decode = require("cjson.safe").new().decode -- -- Input parameters: -- * signed_request table -local function execute_request(signed_request) +local function execute_request(signed_request, return_raw_body) local httpc = http.new() httpc:set_timeout(60000) @@ -49,6 +49,17 @@ local function execute_request(signed_request) local body do if response.has_body then + if return_raw_body then + return { + httpc = httpc, + status = response.status, + reason = response.reason, + headers = response.headers, + has_body = response.has_body, + body_reader = response.body_reader, + read_body = response.read_body, + } + end body, err = response:read_body() if not body then return nil, ("failed reading response body from '%s:%s': %s"):format( diff --git a/src/resty/aws/request/validate.lua b/src/resty/aws/request/validate.lua index 6cfbab7..a40cf3d 100644 --- a/src/resty/aws/request/validate.lua +++ b/src/resty/aws/request/validate.lua @@ -435,6 +435,9 @@ local validators do type = always_pass, deprecated = always_pass, box = always_pass, + locationName = always_pass, + location = always_pass, + deprecatedMessage = always_pass, },ops_mt)