@@ -91,27 +91,19 @@ local function canonicalise_query_string(query)
91
91
end
92
92
93
93
local function get_canonical_headers (headers )
94
- local canonical_headers , signed_headers do
95
- -- We structure this code in a way so that we only have to sort once.
96
- canonical_headers , signed_headers = {}, {}
97
- local i = 0
98
- for name , value in pairs (headers ) do
99
- if value then -- ignore headers with 'false', they are used to override defaults
100
- i = i + 1
101
- local name_lower = name :lower ()
102
- signed_headers [i ] = name_lower
103
- canonical_headers [name_lower ] = pl_string .strip (value )
104
- end
105
- end
106
- table.sort (signed_headers )
107
- for j = 1 , i do
108
- local name = signed_headers [j ]
109
- local value = canonical_headers [name ]
110
- canonical_headers [j ] = name .. " :" .. value .. " \n "
111
- end
112
- signed_headers = table.concat (signed_headers , " ;" , 1 , i )
113
- canonical_headers = table.concat (canonical_headers , nil , 1 , i )
94
+ local signed_headers_arr = {}
95
+ local canonical_headers = " "
96
+
97
+ -- sorting all header names after inserting in an array
98
+ for header_key in pairs (headers ) do table.insert (signed_headers_arr , header_key :lower ()) end
99
+ table.sort (signed_headers_arr )
100
+
101
+ -- going over the sorted array and adding the header and header values to the canonical headers
102
+ local signed_headers = table.concat (signed_headers_arr , " ;" , 1 )
103
+ for _ , header_key in pairs (signed_headers_arr ) do
104
+ canonical_headers = canonical_headers .. header_key .. " :" .. pl_string .strip (headers [header_key ]) .. " \n "
114
105
end
106
+
115
107
return {
116
108
canonical_headers = canonical_headers ,
117
109
signed_headers = signed_headers
@@ -136,7 +128,7 @@ local function prepare_awsv4_request(opts)
136
128
local secret_key = opts .secret_key
137
129
138
130
local request_headers = opts .headers or {}
139
- local request_payload = opts .body
131
+ local request_body = opts .body
140
132
local request_query = opts .query
141
133
142
134
local timestamp = ngx .time ()
@@ -146,6 +138,9 @@ local function prepare_awsv4_request(opts)
146
138
local canonical_uri = canonicalise_path (opts .path , service )
147
139
local credential_scope = date .. " /" .. region .. " /" .. service .. " /aws4_request"
148
140
141
+
142
+ local bodyHash = to_hex (hash (request_body ))
143
+
149
144
-- If the "standard" port is not in use, the port should be added to the Host header
150
145
local host_header do
151
146
if port == 443 or port == 80 then
@@ -154,56 +149,54 @@ local function prepare_awsv4_request(opts)
154
149
host_header = string.format (" %s:%d" , host , port )
155
150
end
156
151
end
152
+
157
153
request_headers [" host" ] = host_header
154
+ request_headers [" x-amz-content-sha256" ] = bodyHash
155
+
156
+ local expiresInSeconds = 300
158
157
159
158
if not opts .sign_query then
160
159
request_headers [" x-amz-date" ] = request_date
161
160
request_headers [" x-amz-security-token" ] = opts .session_token
162
161
if service == " s3" then
163
- request_headers [" x-amz-expires" ] = " 300"
164
- request_headers [" x-amz-content-sha256" ] = " UNSIGNED-PAYLOAD"
162
+ request_headers [" x-amz-expires" ] = expiresInSeconds .. " "
165
163
end
166
164
end
167
165
168
- local transformed_headers = get_canonical_headers (request_headers )
166
+ local canonical_headers = get_canonical_headers (request_headers )
169
167
170
168
if opts .sign_query then
171
- local expires = " "
169
+ local expires_query_param = " "
172
170
if service == " s3" then
173
- expires = " &X-Amz-Expires=300 "
171
+ expires_query_param = " &X-Amz-Expires=" .. expiresInSeconds
174
172
end
175
173
176
- request_query = request_query .. " &X-Amz-Security-Token=" .. url_encode (opts .session_token )
177
- .. expires
174
+ request_query = request_query
175
+ .. " &X-Amz-Security-Token=" .. url_encode (opts .session_token )
176
+ .. expires_query_param
178
177
.. " &X-Amz-Date=" .. request_date
179
178
.. " &X-Amz-Algorithm=" .. ALGORITHM
180
179
.. " &X-Amz-Credential=" .. access_key .. " /" .. credential_scope
181
- .. " &X-Amz-SignedHeaders=" .. transformed_headers .signed_headers
180
+ .. " &X-Amz-SignedHeaders=" .. canonical_headers .signed_headers
182
181
end
183
182
184
183
request_query = removeCharFromStart (request_query , " &" )
185
184
local canonical_querystring = canonicalise_query_string (request_query )
186
185
187
186
-- Task 1: Create a Canonical Request For Signature Version 4
188
187
-- http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
189
- local bodyHash = to_hex (hash (request_payload or " " ))
190
- if service == " s3" then
191
- bodyHash = " UNSIGNED-PAYLOAD"
192
- end
193
-
194
188
local canonical_request =
195
189
request_method .. ' \n ' ..
196
190
canonical_uri .. ' \n ' ..
197
191
(canonical_querystring or " " ) .. ' \n ' ..
198
- transformed_headers .canonical_headers .. ' \n ' ..
199
- transformed_headers .signed_headers .. ' \n ' ..
192
+ canonical_headers .canonical_headers .. ' \n ' ..
193
+ canonical_headers .signed_headers .. ' \n ' ..
200
194
bodyHash
201
195
202
196
local hashed_canonical_request = to_hex (hash (canonical_request ))
203
197
204
198
-- Task 2: Create a String to Sign for Signature Version 4
205
199
-- http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
206
-
207
200
local string_to_sign =
208
201
ALGORITHM .. ' \n ' ..
209
202
request_date .. ' \n ' ..
@@ -221,10 +214,11 @@ local function prepare_awsv4_request(opts)
221
214
if opts .sign_query then
222
215
request_query = request_query .. " &X-Amz-Signature=" .. signature
223
216
else
224
- request_headers [ " authorization " ] = ALGORITHM
217
+ local auth_header = ALGORITHM
225
218
.. " Credential=" .. access_key .. " /" .. credential_scope
226
- .. " , SignedHeaders=" .. transformed_headers .signed_headers
219
+ .. " , SignedHeaders=" .. canonical_headers .signed_headers
227
220
.. " , Signature=" .. signature
221
+ request_headers [" authorization" ] = auth_header
228
222
end
229
223
230
224
return {
@@ -233,4 +227,4 @@ local function prepare_awsv4_request(opts)
233
227
}
234
228
end
235
229
236
- return prepare_awsv4_request
230
+ return prepare_awsv4_request
0 commit comments