Есть ли у вас представление о том, почему следующий код вызывает ошибку: ERR_CONTENT_LENGTH_MISMATCH
?
Если я установил res.setHeader('content-length', 0);
, то ошибки не будет.Вероятно, потому что фактический вывод пуст.Что заставляет content-length
соответствовать фактическому выводу.
Если я установлю res.setHeader('content-length', output.length);
, то возникнет ошибка.Вероятно, потому что output.length
равно 40, но фактическая длина вывода составляет: 0.
// run
$ node 01.js
содержимое файла: 01.js
var express = require('express');
var http = require('http');
var proxy = require('http-proxy-middleware');
function bodyTransform(body) {
body = body.replace('is running', 'is now running');
body = body.replace('3001', '3002');
return body;
}
var onProxyRes = (proxyRes, req, res) => {
const _writeHead = res.writeHead;
const _end = res.end;
var buffer = new Buffer('');
let body = '';
proxyRes.on('data', (chunk) => {
console.log("inside: .on('data', ...)");
buffer = Buffer.concat([buffer, chunk]);
});
proxyRes.on('end', () => {
console.log("inside: .on('end', ...)");
body = buffer.toString('utf8');
});
// defer writeHead
res.writeHead = (...writeHeadArgs) => {
const output = bodyTransform(body);
if (proxyRes.headers && proxyRes.headers['content-length']) {
// if 'content-length' is set to: 'output.length' it causes:
// ERR_CONTENT_LENGTH_MISMATCH (Google Chrome is explicit about the error)
// because it seems that the actual content output is an empty string (length: 0)
res.setHeader('content-length', output.length);
console.log('assigned => content-length: ' + output.length);
// if the following line is uncommented, there are no errors
// because it seems that the actual content output is an empty string (length: 0)
// so the 'content-length' will match
// res.setHeader('content-length', 0);
}
// disabling chunked encoding
res.setHeader('transfer-encoding', '');
// disabling cache for all http as well
res.setHeader('cache-control', 'no-cache');
_writeHead.apply(res, writeHeadArgs);
};
// defer all writes
res.write = (chunk) => { };
res.end = (...endArgs) => {
const output = bodyTransform(body);
if (body.length) {
_end.apply(res, [output]);
}
else {
_end.apply(res, endArgs);
}
console.log('after: _end.apply(...);');
};
}
const portApp01 = 3001;
const app01 = express()
app01.get('/', (req, res) => {
res.send('This server is running on port: 3001');
});
app01.listen(portApp01, () => {
console.log('app01 is listening on port: ' + portApp01);
});
const portProxy = 3002;
const appProxy = express()
appProxy.use(proxy('/', { target: 'http://localhost:3001', onProxyRes: onProxyRes }));
http.createServer(appProxy).listen(portProxy, function () {
console.log('appProxy is listening on port: ' + portProxy);
});
Вывод на терминал:
inside: .on('data', ...)
inside: .on('end', ...)
assigned => content-length: 40
after: _end.apply(...);
Мне кажется, я опускаю очень мелкие детали.
У вас есть идеи, как сделать эту работу?
Спасибо.