Skip to content

Commit 61a3b01

Browse files
committed
CLDSRV-894: fix turn-around time for 0-byte PutObject/UploadPart
The previous fix attached a `request.on('end', ...)` listener to set startTurnAroundTime. For non-empty uploads the downstream API handler consumes the body, which drives the stream to emit 'end'. For 0-byte uploads nothing consumes the stream, so 'end' never fires and startTurnAroundTime stays undefined, causing the access log to render turn-around time as '-'. Detect Content-Length: 0 and set startTurnAroundTime synchronously in that case; keep the 'end' listener for the non-empty path.
1 parent 638c986 commit 61a3b01

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

lib/api/api.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,19 @@ const api = {
263263
request.serverAccessLog.analyticsUserName = authNames.userName;
264264
}
265265
if (apiMethod === 'objectPut' || apiMethod === 'objectPutPart') {
266-
request.on('end', () => {
266+
const setStartTurnAroundTime = () => {
267267
if (request.serverAccessLog) {
268268
request.serverAccessLog.startTurnAroundTime = process.hrtime.bigint();
269269
}
270-
});
270+
};
271+
// For 0-byte uploads, downstream handlers do not consume
272+
// the request stream, so 'end' never fires. Set
273+
// startTurnAroundTime synchronously in that case.
274+
if (request.headers['content-length'] === '0') {
275+
setStartTurnAroundTime();
276+
} else {
277+
request.on('end', setStartTurnAroundTime);
278+
}
271279
return next(null, userInfo, authorizationResults, streamingV4Params, infos);
272280
}
273281
// issue 100 Continue to the client

tests/unit/api/api.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,21 @@ describe('api.callApiMethod', () => {
132132
done();
133133
});
134134
});
135+
136+
it(`should set startTurnAroundTime synchronously for 0-byte ${method}`, done => {
137+
sandbox.stub(api, method).callsFake(
138+
(userInfo, _request, streamingV4Params, _log, cb) => {
139+
assert.strictEqual(typeof request.serverAccessLog.startTurnAroundTime, 'bigint');
140+
cb();
141+
});
142+
request.objectKey = 'testobject';
143+
request.serverAccessLog = {};
144+
request.headers = Object.assign({}, request.headers, { 'content-length': '0' });
145+
api.callApiMethod(method, request, response, log, err => {
146+
assert.ifError(err);
147+
done();
148+
});
149+
});
135150
});
136151

137152
describe('MD5 checksum validation', () => {

0 commit comments

Comments
 (0)