Skip to content

Commit 7f27c00

Browse files
authored
HTTPServer: Dynamically create and clean up XDG dirs on each request if not exists (#756)
1 parent a43023c commit 7f27c00

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/browser/browser.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,16 @@ export class Browser {
122122
}
123123
}
124124

125-
getLauncherOptions(options) {
125+
getLauncherOptions(options: Partial<RenderOptions>) {
126126
const env = Object.assign({}, process.env);
127127
// set env timezone
128128
env.TZ = options.timezone || this.config.timezone;
129129

130130
const launcherOptions: PuppeteerLaunchOptions = {
131-
env: env,
131+
env: {
132+
...env,
133+
...(options.extraEnv && { ...options.extraEnv }),
134+
},
132135
ignoreHTTPSErrors: this.config.ignoresHttpsErrors,
133136
dumpio: this.config.dumpio,
134137
args: this.config.args,

src/service/http-server.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import morgan from 'morgan';
99
import multer from 'multer';
1010
import net from 'net';
1111
import path from 'path';
12+
import os from 'os';
1213
import * as promClient from 'prom-client';
1314

1415
import { Logger } from '../logger';
@@ -206,9 +207,18 @@ export class HttpServer {
206207
headers: this.getHeaders(req),
207208
};
208209

210+
const xdgTempDir = await this.createTempXdgDir();
211+
if (xdgTempDir) {
212+
options.extraEnv = {
213+
XDG_CACHE_HOME: process.env?.['XDG_CACHE_HOME'] || xdgTempDir,
214+
XDG_CONFIG_HOME: process.env?.['XDG_CONFIG_HOME'] || xdgTempDir,
215+
};
216+
}
217+
209218
this.log.debug('Render request received', 'url', options.url);
210219
req.on('close', (err) => {
211220
this.log.debug('Connection closed', 'url', options.url, 'error', err);
221+
this.removeTempXdgDir(xdgTempDir);
212222
abortController.abort();
213223
});
214224

@@ -290,9 +300,18 @@ export class HttpServer {
290300
headers: this.getHeaders(req),
291301
};
292302

303+
const xdgTempDir = await this.createTempXdgDir();
304+
if (xdgTempDir) {
305+
options.extraEnv = {
306+
XDG_CACHE_HOME: process.env?.['XDG_CACHE_HOME'] || xdgTempDir,
307+
XDG_CONFIG_HOME: process.env?.['XDG_CONFIG_HOME'] || xdgTempDir,
308+
};
309+
}
310+
293311
this.log.debug('Render request received', 'url', options.url);
294312
req.on('close', (err) => {
295313
this.log.debug('Connection closed', 'url', options.url, 'error', err);
314+
this.removeTempXdgDir(xdgTempDir);
296315
abortController.abort();
297316
});
298317

@@ -343,4 +362,38 @@ export class HttpServer {
343362

344363
return headers;
345364
}
365+
366+
async createTempXdgDir(): Promise<string | null> {
367+
// If both are set, we can skip creating the temp dir.
368+
if (process.env?.['XDG_CACHE_HOME'] && process.env?.['XDG_CONFIG_HOME']) {
369+
return null;
370+
}
371+
372+
let xdgTempDir: string | null = null;
373+
374+
try {
375+
xdgTempDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'xdg-'));
376+
if (!xdgTempDir) {
377+
throw new Error('fs.promises.mkdtemp returned a null dir');
378+
}
379+
380+
this.log.debug('Created temporary XDG directory', 'dir', xdgTempDir);
381+
} catch (e) {
382+
this.log.error('Failed to create temporary XDG directory', 'error', e.message);
383+
}
384+
385+
return xdgTempDir;
386+
}
387+
388+
removeTempXdgDir(xdgTempDir: string | null) {
389+
if (xdgTempDir) {
390+
fs.rm(xdgTempDir, { recursive: true, maxRetries: 3 }, (err) => {
391+
if (err) {
392+
this.log.error('Failed to delete temporary XDG directory', 'dir', xdgTempDir, 'error', err.message);
393+
} else {
394+
this.log.debug('Deleted temporary XDG directory', 'dir', xdgTempDir);
395+
}
396+
});
397+
}
398+
}
346399
}

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface RenderOptions {
1313
timezone?: string;
1414
encoding?: string;
1515
headers?: HTTPHeaders;
16+
extraEnv?: typeof process.env;
1617
}
1718

1819
export interface ImageRenderOptions extends RenderOptions {

0 commit comments

Comments
 (0)