diff --git a/src/commands/webdav-config.ts b/src/commands/webdav-config.ts index bae80948..51896c5c 100644 --- a/src/commands/webdav-config.ts +++ b/src/commands/webdav-config.ts @@ -28,6 +28,12 @@ export default class WebDAVConfig extends Command { required: false, exclusive: ['https'], }), + timeout: Flags.integer({ + char: 't', + description: 'Configures the WebDAV server to use this timeout in minutes.', + required: false, + min: 0, + }), }; static readonly enableJsonFlag = true; @@ -54,6 +60,11 @@ export default class WebDAVConfig extends Command { webdavConfig['protocol'] = 'https'; } + const timeout = flags['timeout']; + if (timeout) { + webdavConfig['timeoutMinutes'] = timeout; + } + await ConfigService.instance.saveWebdavConfig(webdavConfig); const message = `On the next start, the WebDAV server will use the next config: ${JSON.stringify(webdavConfig)}`; CLIUtils.success(this.log.bind(this), message); diff --git a/src/services/config.service.ts b/src/services/config.service.ts index 62d7483c..88d89ded 100644 --- a/src/services/config.service.ts +++ b/src/services/config.service.ts @@ -16,6 +16,7 @@ export class ConfigService { static readonly WEBDAV_LOCAL_URL = 'webdav.local.internxt.com'; static readonly WEBDAV_DEFAULT_PORT = '3005'; static readonly WEBDAV_DEFAULT_PROTOCOL = 'https'; + static readonly WEBDAV_DEFAULT_TIMEOUT = 0; public static readonly instance: ConfigService = new ConfigService(); /** @@ -87,11 +88,13 @@ export class ConfigService { return { port: configs?.port ?? ConfigService.WEBDAV_DEFAULT_PORT, protocol: configs?.protocol ?? ConfigService.WEBDAV_DEFAULT_PROTOCOL, + timeoutMinutes: configs?.timeoutMinutes ?? ConfigService.WEBDAV_DEFAULT_TIMEOUT, }; } catch { return { port: ConfigService.WEBDAV_DEFAULT_PORT, protocol: ConfigService.WEBDAV_DEFAULT_PROTOCOL, + timeoutMinutes: ConfigService.WEBDAV_DEFAULT_TIMEOUT, }; } }; diff --git a/src/types/command.types.ts b/src/types/command.types.ts index a32c3160..ae741464 100644 --- a/src/types/command.types.ts +++ b/src/types/command.types.ts @@ -11,6 +11,7 @@ export interface LoginCredentials { export interface WebdavConfig { port: string; protocol: 'http' | 'https'; + timeoutMinutes: number; } export class NotValidEmailError extends Error { diff --git a/src/webdav/webdav-server.ts b/src/webdav/webdav-server.ts index 7062f70c..96531915 100644 --- a/src/webdav/webdav-server.ts +++ b/src/webdav/webdav-server.ts @@ -177,8 +177,8 @@ export class WebDavServer { server = https.createServer(httpsCerts, this.app); } - // Allow long uploads/downloads from WebDAV clients (up to 15 minutes before closing connection): - server.requestTimeout = 15 * 60 * 1000; + // Allow long uploads/downloads from WebDAV clients: + server.requestTimeout = configs.timeoutMinutes * 60 * 1000; server.listen(configs.port, () => { webdavLogger.info( diff --git a/test/services/config.service.test.ts b/test/services/config.service.test.ts index f1fc9aad..7f10b236 100644 --- a/test/services/config.service.test.ts +++ b/test/services/config.service.test.ts @@ -121,6 +121,7 @@ describe('Config service', () => { const webdavConfig: WebdavConfig = { port: String(crypto.randomInt(65000)), protocol: 'https', + timeoutMinutes: crypto.randomInt(100), }; const stringConfig = JSON.stringify(webdavConfig); @@ -134,6 +135,7 @@ describe('Config service', () => { const webdavConfig: WebdavConfig = { port: String(crypto.randomInt(65000)), protocol: 'http', + timeoutMinutes: crypto.randomInt(100), }; const stringConfig = JSON.stringify(webdavConfig); @@ -148,6 +150,7 @@ describe('Config service', () => { const defaultWebdavConfig: WebdavConfig = { port: ConfigService.WEBDAV_DEFAULT_PORT, protocol: ConfigService.WEBDAV_DEFAULT_PROTOCOL, + timeoutMinutes: ConfigService.WEBDAV_DEFAULT_TIMEOUT, }; const fsStub = vi.spyOn(fs, 'readFile').mockResolvedValue(''); @@ -161,6 +164,7 @@ describe('Config service', () => { const defaultWebdavConfig: WebdavConfig = { port: ConfigService.WEBDAV_DEFAULT_PORT, protocol: ConfigService.WEBDAV_DEFAULT_PROTOCOL, + timeoutMinutes: ConfigService.WEBDAV_DEFAULT_TIMEOUT, }; const fsStub = vi.spyOn(fs, 'readFile').mockRejectedValue(new Error());