Skip to content

Commit

Permalink
fix(request): build request body by operation payload field (#126)
Browse files Browse the repository at this point in the history
This is a follow-up fix for #120 .

The PR modifies the request build again with the following changes: when the payload field is specified inside the input schema, the request body will be built based on the parameter that specified by the payload field.

This behavior imitates the behavior defined in aws-sdk-js: https://github.com/aws/aws-sdk-js/blob/02153340ce052614c5437fe46ab1f49bfd8483f7/lib/protocol/rest_json.js#L24-L41
as well as https://github.com/aws/aws-sdk-js/blob/02153340ce052614c5437fe46ab1f49bfd8483f7/lib/protocol/rest_xml.js#L10-L26

FTI-6138
  • Loading branch information
windmgc authored Aug 2, 2024
1 parent e5b38f7 commit 0f54bd2
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ Release process:
1. test installing the rock from LuaRocks


### Unreleased

- fix: build the request body based on payload field
[126](https://github.com/Kong/lua-resty-aws/pull/126)


### 1.5.2 (29-Jul-2024)

- fix: fix sts regional endpoint injection under several cases
Expand Down
77 changes: 74 additions & 3 deletions spec/02-requests/02-build_request_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ describe("operations protocol", function()


local build_request
local operation
local config
local params
local operation, operation_with_payload_field
local config, config_with_payload
local params, params_with_payload
local snapshot
local binary_data

Expand Down Expand Up @@ -105,6 +105,37 @@ describe("operations protocol", function()
}
}

operation_with_payload_field = {
name = "PutObject",
http = {
method = "PUT",
requestUri = "/{Bucket}/{Key+}"
},
input = {
type = "structure",
required = {
"Bucket",
"Key"
},
members = {
Bucket = {
type = "string",
location = "uri",
locationName = "Bucket"
},
Key = {
type = "string",
location = "uri",
locationName = "Key"
},
Body = {
type = "blob",
},
},
payload = "Body"
},
}

config = {
apiVersion = "2011-06-15",
--endpointPrefix = "sts",
Expand All @@ -119,6 +150,19 @@ describe("operations protocol", function()
xmlNamespace = "https://sts.amazonaws.com/doc/2011-06-15/"
}

config_with_payload = {
apiVersion = "2006-03-01",
signingName = "s3",
globalEndpoint = "s3.amazonaws.com",
--protocol = "query",
serviceAbbreviation = "AWS S3",
serviceFullName = "AWS Object Storage",
serviceId = "S3",
signatureVersion = "v4",
uid = "s3-2006-03-01",
xmlNamespace = "https://s3.amazonaws.com/doc/2006-03-01/"
}

params = {
RoleArn = "hello",
RoleSessionName = "world",
Expand All @@ -134,6 +178,12 @@ describe("operations protocol", function()
BinaryData = binary_data,
}

params_with_payload = {
Bucket = "hello",
Key = "world",
Body = binary_data,
}

end)


Expand Down Expand Up @@ -256,6 +306,27 @@ describe("operations protocol", function()
}, request)
end)

it("json: querystring, uri, header and body params, with payload field", function()

config_with_payload.protocol = "json"

local request = build_request(operation_with_payload_field, config_with_payload, params_with_payload)

assert.same({
headers = {
["Content-Length"] = 4,
["X-Amz-Target"] = "s3.PutObject",
["Host"] = "s3.amazonaws.com",
},
method = 'PUT',
path = '/hello/world',
host = 's3.amazonaws.com',
port = 443,
body = binary_data,
query = {},
}, request)
end)


it("rest-xml: querystring, uri, header and body params", function()

Expand Down
15 changes: 15 additions & 0 deletions src/resty/aws/request/build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,21 @@ local function build_request(operation, config, params)
request.query[k] = v
end

local payload_member = operation.input and operation.input.payload
if payload_member and body_tbl[payload_member] then
local member_config = operation.input.members[payload_member]
if member_config.type == "structure" then
body_tbl = type(body_tbl[payload_member]) == "table" and body_tbl[payload_member] or body_tbl

elseif body_tbl[payload_member] then
request.body = body_tbl[payload_member]
if member_config.type == "binary" and member_config.streaming == true then
request.headers["Content-Type"] = "binary/octet-stream"
end
body_tbl[payload_member] = nil
end
end

local table_empty = not next(body_tbl)
-- already has a raw body, or no body at all
if request.body then
Expand Down

0 comments on commit 0f54bd2

Please sign in to comment.