Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ class S3Server {
});
}

// Starting NodeJS v18, the default timeout, when `undefined`, is
// 5 minutes. We must set the value to zero to allow for long
// upload durations.
server.requestTimeout = 0; // disabling request timeout
Comment thread
benzekrimaha marked this conversation as resolved.

Copy link
Copy Markdown

@ghost ghost Jul 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I suggest adding a unit test:

const assert = require('assert');
const sinon = require('sinon');
const http = require('http');
const https = require('https');
const promClient = require('prom-client');

describe('S3Server request timeout', () => {
    let sandbox;
    let mockServer;

    beforeEach(() => {
        sandbox = sinon.createSandbox();
        
        // Clear prometheus registry to avoid conflicts
        promClient.register.clear();
        
        // Create a mock server to capture the requestTimeout setting
        mockServer = {
            requestTimeout: null,
            on: sandbox.stub(),
            listen: sandbox.stub(),
            address: sandbox.stub().returns({ address: '127.0.0.1', port: 8000 }),
        };
        
        // Mock server creation to return our mock
        sandbox.stub(http, 'createServer').returns(mockServer);
        sandbox.stub(https, 'createServer').returns(mockServer);
    });

    afterEach(() => {
        sandbox.restore();
    });

    it('should set server.requestTimeout to 0 when starting server', () => {
        const { S3Server } = require('../../lib/server');
        const server = new S3Server();
        
        // Call _startServer which should set requestTimeout = 0
        server._startServer(() => {}, 8000, '127.0.0.1');
        
        // Verify that requestTimeout was set to 0
        assert.strictEqual(mockServer.requestTimeout, 0);
    });
});

You'll need to also export the s3Server class from server.js

module.exports.S3Server = S3Server;

I think this is important to avoid missing such issue again in the future.

server.on('connection', socket => {
socket.on('error', err => logger.info('request rejected',
{ error: err }));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenko/cloudserver",
"version": "9.0.19",
"version": "9.0.20",
"description": "Zenko CloudServer, an open-source Node.js implementation of a server handling the Amazon S3 protocol",
"main": "index.js",
"engines": {
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

const assert = require('assert');
const sinon = require('sinon');
const http = require('http');
const https = require('https');
const arsenal = require('arsenal');
const uuid = require('uuid');
const logger = require('../../lib/utilities/logger');
Expand Down Expand Up @@ -210,3 +212,41 @@ describe('S3Server', () => {
});
});
});

describe('S3Server request timeout', () => {
let sandbox;
let mockServer;

beforeEach(() => {
sandbox = sinon.createSandbox();

// Create a mock server to capture the requestTimeout setting
mockServer = {
requestTimeout: null,
on: sandbox.stub(),
listen: sandbox.stub(),
address: sandbox.stub().returns({ address: '127.0.0.1', port: 8000 }),
};

// Mock server creation to return our mock
sandbox.stub(http, 'createServer').returns(mockServer);
sandbox.stub(https, 'createServer').returns(mockServer);
});

afterEach(() => {
sandbox.restore();
});

it('should set server.requestTimeout to 0 when starting server', () => {
const server = new S3Server({
...defaultConfig,
https: false
});

// Call _startServer which should set requestTimeout = 0
server._startServer(() => {}, 8000, '127.0.0.1');

// Verify that requestTimeout was set to 0
assert.strictEqual(mockServer.requestTimeout, 0);
});
});
Loading