Skip to content

Commit 02f0b8c

Browse files
committed
Re-sign requests if they took too long to be sent.
Fixes the root cause of #221. When maxSockets is set to a value lower than the amount of parallel requests, some of those requests can be queued for "a long time". Because signing happens before those requests are queued, their 15 minute signing window can timeout before they ever hit the 'send' event. This change adds an extra check to the 'send' even to force a re-sign of the request if more than 10 minutes passed since the sign event was triggered. This should allow multiple requests to be queued for an indefinite period of time.
2 parents 3e256e0 + b8da7f1 commit 02f0b8c

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

lib/event_listeners.js

+19-6
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ AWS.EventListeners = {
125125

126126
// add new authorization
127127
signer.addAuthorization(credentials, date);
128+
req.signedAt = date;
128129
} catch (e) {
129130
req.response.error = e;
130131
}
@@ -145,6 +146,8 @@ AWS.EventListeners = {
145146

146147
addAsync('SEND', 'send', function SEND(resp, done) {
147148
resp.httpResponse._abortCallback = done;
149+
resp.error = null;
150+
resp.data = null;
148151

149152
function callback(httpResp) {
150153
resp.httpResponse.stream = httpResp;
@@ -196,13 +199,23 @@ AWS.EventListeners = {
196199
});
197200
}
198201

199-
resp.error = null;
200-
resp.data = null;
202+
function executeSend() {
203+
var http = AWS.HttpClient.getInstance();
204+
var httpOptions = resp.request.service.config.httpOptions || {};
205+
var stream = http.handleRequest(resp.request.httpRequest, httpOptions,
206+
callback, error);
207+
progress(stream);
208+
}
201209

202-
var http = AWS.HttpClient.getInstance();
203-
var httpOptions = resp.request.service.config.httpOptions || {};
204-
var s = http.handleRequest(this.httpRequest, httpOptions, callback, error);
205-
progress(s);
210+
var timeDiff = (AWS.util.date.getDate() - this.signedAt) / 1000;
211+
if (timeDiff >= 60 * 10) { // if we signed 10min ago, re-sign
212+
this.emit('sign', [this], function(err) {
213+
if (err) done(err);
214+
else executeSend();
215+
});
216+
} else {
217+
executeSend();
218+
}
206219
});
207220

208221
add('HTTP_HEADERS', 'httpHeaders',

test/event_listeners.spec.coffee

+22
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,28 @@ describe 'AWS.EventListeners', ->
166166
makeRequest(->)
167167
expect(options.timeout).toEqual(15)
168168

169+
it 'signs only once in normal case', ->
170+
signHandler = jasmine.createSpy('sign')
171+
helpers.mockHttpResponse 200, {}, ['data']
172+
173+
request = makeRequest()
174+
request.on('sign', signHandler)
175+
request.build()
176+
request.signedAt = new Date(request.signedAt - 60 * 5 * 1000)
177+
request.send()
178+
expect(signHandler.callCount).toEqual(1)
179+
180+
it 'resigns if it took more than 10 min to get to send', ->
181+
signHandler = jasmine.createSpy('sign')
182+
helpers.mockHttpResponse 200, {}, ['data']
183+
184+
request = makeRequest()
185+
request.on('sign', signHandler)
186+
request.build()
187+
request.signedAt = new Date(request.signedAt - 60 * 12 * 1000)
188+
request.send()
189+
expect(signHandler.callCount).toEqual(2)
190+
169191
describe 'httpData', ->
170192
beforeEach ->
171193
helpers.mockHttpResponse 200, {}, ['FOO', 'BAR', 'BAZ', 'QUX']

0 commit comments

Comments
 (0)