Skip to content

Commit 84ff20f

Browse files
authored
test: fix test server on Node 15 (#4668)
This patch fixes a bug in our test server that manifests itself in Node 15. Context: Node 14 does not support Apple Silicon (and probably will not), so we currently have to run tests on Node 15 on new macs.
1 parent b486e84 commit 84ff20f

File tree

1 file changed

+29
-22
lines changed

1 file changed

+29
-22
lines changed

utils/testserver/index.js

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,16 @@ const https = require('https');
1919
const url = require('url');
2020
const fs = require('fs');
2121
const path = require('path');
22+
const zlib = require('zlib');
23+
const util = require('util');
2224
const WebSocketServer = require('ws').Server;
2325

2426
const fulfillSymbol = Symbol('fullfil callback');
2527
const rejectSymbol = Symbol('reject callback');
2628

29+
const readFileAsync = util.promisify(fs.readFile.bind(fs));
30+
const gzipAsync = util.promisify(zlib.gzip.bind(zlib));
31+
2732
class TestServer {
2833
/**
2934
* @param {string} dirPath
@@ -236,7 +241,7 @@ class TestServer {
236241
* @param {!http.ServerResponse} response
237242
* @param {string|undefined} filePath
238243
*/
239-
serveFile(request, response, filePath) {
244+
async serveFile(request, response, filePath) {
240245
let pathName = url.parse(request.url).path;
241246
if (!filePath) {
242247
if (pathName === '/')
@@ -258,27 +263,29 @@ class TestServer {
258263
if (this._csp.has(pathName))
259264
response.setHeader('Content-Security-Policy', this._csp.get(pathName));
260265

261-
fs.readFile(filePath, (err, data) => {
262-
if (err) {
263-
response.statusCode = 404;
264-
response.end(`File not found: ${filePath}`);
265-
return;
266-
}
267-
const extension = filePath.substring(filePath.lastIndexOf('.') + 1);
268-
const mimeType = extensionToMime[extension] || 'application/octet-stream';
269-
const isTextEncoding = /^text\/|^application\/(javascript|json)/.test(mimeType);
270-
const contentType = isTextEncoding ? `${mimeType}; charset=utf-8` : mimeType;
271-
response.setHeader('Content-Type', contentType);
272-
if (this._gzipRoutes.has(pathName)) {
273-
response.setHeader('Content-Encoding', 'gzip');
274-
const zlib = require('zlib');
275-
zlib.gzip(data, (_, result) => {
276-
response.end(result);
277-
});
278-
} else {
279-
response.end(data);
280-
}
281-
});
266+
const {err, data} = await readFileAsync(filePath).then(data => ({data})).catch(err => ({err}));
267+
// The HTTP transaction might be already terminated after async hop here - do nothing in this case.
268+
if (response.writableEnded)
269+
return;
270+
if (err) {
271+
response.statusCode = 404;
272+
response.end(`File not found: ${filePath}`);
273+
return;
274+
}
275+
const extension = filePath.substring(filePath.lastIndexOf('.') + 1);
276+
const mimeType = extensionToMime[extension] || 'application/octet-stream';
277+
const isTextEncoding = /^text\/|^application\/(javascript|json)/.test(mimeType);
278+
const contentType = isTextEncoding ? `${mimeType}; charset=utf-8` : mimeType;
279+
response.setHeader('Content-Type', contentType);
280+
if (this._gzipRoutes.has(pathName)) {
281+
response.setHeader('Content-Encoding', 'gzip');
282+
const result = await gzipAsync(data);
283+
// The HTTP transaction might be already terminated after async hop here.
284+
if (!response.writableEnded)
285+
response.end(result);
286+
} else {
287+
response.end(data);
288+
}
282289
}
283290

284291
_onWebSocketConnection(ws) {

0 commit comments

Comments
 (0)