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.
This commit is contained in:
Andrey Lushnikov 2020-12-10 09:47:06 -08:00 коммит произвёл GitHub
Родитель b486e840ad
Коммит 84ff20f193
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 29 добавлений и 22 удалений

Просмотреть файл

@ -19,11 +19,16 @@ const https = require('https');
const url = require('url');
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const util = require('util');
const WebSocketServer = require('ws').Server;
const fulfillSymbol = Symbol('fullfil callback');
const rejectSymbol = Symbol('reject callback');
const readFileAsync = util.promisify(fs.readFile.bind(fs));
const gzipAsync = util.promisify(zlib.gzip.bind(zlib));
class TestServer {
/**
* @param {string} dirPath
@ -236,7 +241,7 @@ class TestServer {
* @param {!http.ServerResponse} response
* @param {string|undefined} filePath
*/
serveFile(request, response, filePath) {
async serveFile(request, response, filePath) {
let pathName = url.parse(request.url).path;
if (!filePath) {
if (pathName === '/')
@ -258,7 +263,10 @@ class TestServer {
if (this._csp.has(pathName))
response.setHeader('Content-Security-Policy', this._csp.get(pathName));
fs.readFile(filePath, (err, data) => {
const {err, data} = await readFileAsync(filePath).then(data => ({data})).catch(err => ({err}));
// The HTTP transaction might be already terminated after async hop here - do nothing in this case.
if (response.writableEnded)
return;
if (err) {
response.statusCode = 404;
response.end(`File not found: ${filePath}`);
@ -271,14 +279,13 @@ class TestServer {
response.setHeader('Content-Type', contentType);
if (this._gzipRoutes.has(pathName)) {
response.setHeader('Content-Encoding', 'gzip');
const zlib = require('zlib');
zlib.gzip(data, (_, result) => {
const result = await gzipAsync(data);
// The HTTP transaction might be already terminated after async hop here.
if (!response.writableEnded)
response.end(result);
});
} else {
response.end(data);
}
});
}
_onWebSocketConnection(ws) {