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 committed by GitHub
parent b486e840ad
commit 84ff20f193
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -19,11 +19,16 @@ const https = require('https');
const url = require('url'); const url = require('url');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const zlib = require('zlib');
const util = require('util');
const WebSocketServer = require('ws').Server; const WebSocketServer = require('ws').Server;
const fulfillSymbol = Symbol('fullfil callback'); const fulfillSymbol = Symbol('fullfil callback');
const rejectSymbol = Symbol('reject callback'); const rejectSymbol = Symbol('reject callback');
const readFileAsync = util.promisify(fs.readFile.bind(fs));
const gzipAsync = util.promisify(zlib.gzip.bind(zlib));
class TestServer { class TestServer {
/** /**
* @param {string} dirPath * @param {string} dirPath
@ -236,7 +241,7 @@ class TestServer {
* @param {!http.ServerResponse} response * @param {!http.ServerResponse} response
* @param {string|undefined} filePath * @param {string|undefined} filePath
*/ */
serveFile(request, response, filePath) { async serveFile(request, response, filePath) {
let pathName = url.parse(request.url).path; let pathName = url.parse(request.url).path;
if (!filePath) { if (!filePath) {
if (pathName === '/') if (pathName === '/')
@ -258,27 +263,29 @@ class TestServer {
if (this._csp.has(pathName)) if (this._csp.has(pathName))
response.setHeader('Content-Security-Policy', this._csp.get(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}));
if (err) { // The HTTP transaction might be already terminated after async hop here - do nothing in this case.
response.statusCode = 404; if (response.writableEnded)
response.end(`File not found: ${filePath}`); return;
return; if (err) {
} response.statusCode = 404;
const extension = filePath.substring(filePath.lastIndexOf('.') + 1); response.end(`File not found: ${filePath}`);
const mimeType = extensionToMime[extension] || 'application/octet-stream'; return;
const isTextEncoding = /^text\/|^application\/(javascript|json)/.test(mimeType); }
const contentType = isTextEncoding ? `${mimeType}; charset=utf-8` : mimeType; const extension = filePath.substring(filePath.lastIndexOf('.') + 1);
response.setHeader('Content-Type', contentType); const mimeType = extensionToMime[extension] || 'application/octet-stream';
if (this._gzipRoutes.has(pathName)) { const isTextEncoding = /^text\/|^application\/(javascript|json)/.test(mimeType);
response.setHeader('Content-Encoding', 'gzip'); const contentType = isTextEncoding ? `${mimeType}; charset=utf-8` : mimeType;
const zlib = require('zlib'); response.setHeader('Content-Type', contentType);
zlib.gzip(data, (_, result) => { if (this._gzipRoutes.has(pathName)) {
response.end(result); response.setHeader('Content-Encoding', 'gzip');
}); const result = await gzipAsync(data);
} else { // The HTTP transaction might be already terminated after async hop here.
response.end(data); if (!response.writableEnded)
} response.end(result);
}); } else {
response.end(data);
}
} }
_onWebSocketConnection(ws) { _onWebSocketConnection(ws) {