mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
Fixed Z_BUF_ERROR when content-encoding is set but the response body is empty; (#5250)
Fixed download progress capturing for compressed responses; Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
+18
-18
@@ -373,6 +373,23 @@ export default function httpAdapter(config) {
|
|||||||
|
|
||||||
const streams = [res];
|
const streams = [res];
|
||||||
|
|
||||||
|
const responseLength = +res.headers['content-length'];
|
||||||
|
|
||||||
|
if (onDownloadProgress) {
|
||||||
|
const transformStream = new AxiosTransformStream({
|
||||||
|
length: utils.toFiniteNumber(responseLength),
|
||||||
|
maxRate: utils.toFiniteNumber(maxDownloadRate)
|
||||||
|
});
|
||||||
|
|
||||||
|
onDownloadProgress && transformStream.on('progress', progress => {
|
||||||
|
onDownloadProgress(Object.assign(progress, {
|
||||||
|
download: true
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
streams.push(transformStream);
|
||||||
|
}
|
||||||
|
|
||||||
// uncompress the response body transparently if required
|
// uncompress the response body transparently if required
|
||||||
let responseStream = res;
|
let responseStream = res;
|
||||||
|
|
||||||
@@ -383,7 +400,7 @@ export default function httpAdapter(config) {
|
|||||||
if (config.decompress !== false) {
|
if (config.decompress !== false) {
|
||||||
// if no content, but headers still say that it is encoded,
|
// if no content, but headers still say that it is encoded,
|
||||||
// remove the header not confuse downstream operations
|
// remove the header not confuse downstream operations
|
||||||
if (data && data.length === 0 && res.headers['content-encoding']) {
|
if ((!responseLength || res.statusCode === 204) && res.headers['content-encoding']) {
|
||||||
delete res.headers['content-encoding'];
|
delete res.headers['content-encoding'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,23 +423,6 @@ export default function httpAdapter(config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onDownloadProgress) {
|
|
||||||
const responseLength = +res.headers['content-length'];
|
|
||||||
|
|
||||||
const transformStream = new AxiosTransformStream({
|
|
||||||
length: utils.toFiniteNumber(responseLength),
|
|
||||||
maxRate: utils.toFiniteNumber(maxDownloadRate)
|
|
||||||
});
|
|
||||||
|
|
||||||
onDownloadProgress && transformStream.on('progress', progress => {
|
|
||||||
onDownloadProgress(Object.assign(progress, {
|
|
||||||
download: true
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
streams.push(transformStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];
|
responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];
|
||||||
|
|
||||||
const offListeners = stream.finished(responseStream, () => {
|
const offListeners = stream.finished(responseStream, () => {
|
||||||
|
|||||||
+58
-41
@@ -47,9 +47,14 @@ var noop = ()=> {};
|
|||||||
|
|
||||||
const LOCAL_SERVER_URL = 'http://localhost:4444';
|
const LOCAL_SERVER_URL = 'http://localhost:4444';
|
||||||
|
|
||||||
function startHTTPServer({useBuffering= false, rate = undefined, port = 4444} = {}) {
|
function startHTTPServer(options) {
|
||||||
|
|
||||||
|
const {handler, useBuffering = false, rate = undefined, port = 4444} = typeof options === 'function' ? {
|
||||||
|
handler: options
|
||||||
|
} : options || {};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
http.createServer(async function (req, res) {
|
http.createServer(handler || async function (req, res) {
|
||||||
try {
|
try {
|
||||||
req.headers['content-length'] && res.setHeader('content-length', req.headers['content-length']);
|
req.headers['content-length'] && res.setHeader('content-length', req.headers['content-length']);
|
||||||
|
|
||||||
@@ -426,59 +431,72 @@ describe('supports http with nodejs', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support transparent gunzip', function (done) {
|
describe('compression', () => {
|
||||||
var data = {
|
it('should support transparent gunzip', function (done) {
|
||||||
firstName: 'Fred',
|
var data = {
|
||||||
lastName: 'Flintstone',
|
firstName: 'Fred',
|
||||||
emailAddr: 'fred@example.com'
|
lastName: 'Flintstone',
|
||||||
};
|
emailAddr: 'fred@example.com'
|
||||||
|
};
|
||||||
|
|
||||||
zlib.gzip(JSON.stringify(data), function (err, zipped) {
|
zlib.gzip(JSON.stringify(data), function (err, zipped) {
|
||||||
|
|
||||||
server = http.createServer(function (req, res) {
|
server = http.createServer(function (req, res) {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.setHeader('Content-Encoding', 'gzip');
|
res.setHeader('Content-Encoding', 'gzip');
|
||||||
res.end(zipped);
|
res.end(zipped);
|
||||||
}).listen(4444, function () {
|
}).listen(4444, function () {
|
||||||
axios.get('http://localhost:4444/').then(function (res) {
|
axios.get('http://localhost:4444/').then(function (res) {
|
||||||
assert.deepEqual(res.data, data);
|
assert.deepEqual(res.data, data);
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should support gunzip error handling', function (done) {
|
it('should support gunzip error handling', async () => {
|
||||||
server = http.createServer(function (req, res) {
|
server = await startHTTPServer((req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.setHeader('Content-Encoding', 'gzip');
|
res.setHeader('Content-Encoding', 'gzip');
|
||||||
res.end('invalid response');
|
res.end('invalid response');
|
||||||
}).listen(4444, function () {
|
|
||||||
axios.get('http://localhost:4444/').catch(function (error) {
|
|
||||||
done();
|
|
||||||
}).catch(done);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await assert.rejects(async ()=> {
|
||||||
|
await axios.get(LOCAL_SERVER_URL);
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support disabling automatic decompression of response data', function(done) {
|
it('should support disabling automatic decompression of response data', function(done) {
|
||||||
var data = 'Test data';
|
var data = 'Test data';
|
||||||
|
|
||||||
zlib.gzip(data, function(err, zipped) {
|
zlib.gzip(data, function(err, zipped) {
|
||||||
server = http.createServer(function(req, res) {
|
server = http.createServer(function(req, res) {
|
||||||
res.setHeader('Content-Type', 'text/html;charset=utf-8');
|
res.setHeader('Content-Type', 'text/html;charset=utf-8');
|
||||||
res.setHeader('Content-Encoding', 'gzip');
|
res.setHeader('Content-Encoding', 'gzip');
|
||||||
res.end(zipped);
|
res.end(zipped);
|
||||||
}).listen(4444, function() {
|
}).listen(4444, function() {
|
||||||
axios.get('http://localhost:4444/', {
|
axios.get('http://localhost:4444/', {
|
||||||
decompress: false,
|
decompress: false,
|
||||||
responseType: 'arraybuffer'
|
responseType: 'arraybuffer'
|
||||||
|
|
||||||
}).then(function(res) {
|
}).then(function(res) {
|
||||||
assert.equal(res.data.toString('base64'), zipped.toString('base64'));
|
assert.equal(res.data.toString('base64'), zipped.toString('base64'));
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should properly handle empty responses without Z_BUF_ERROR throwing', async () => {
|
||||||
|
this.timeout(10000);
|
||||||
|
|
||||||
|
server = await startHTTPServer((req, res) => {
|
||||||
|
res.setHeader('Content-Encoding', 'gzip');
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
await axios.get(LOCAL_SERVER_URL);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support UTF8', function (done) {
|
it('should support UTF8', function (done) {
|
||||||
@@ -1887,7 +1905,6 @@ describe('supports http with nodejs', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('request aborting', function() {
|
describe('request aborting', function() {
|
||||||
it('should be able to abort the response stream', async function () {
|
it('should be able to abort the response stream', async function () {
|
||||||
server = await startHTTPServer({
|
server = await startHTTPServer({
|
||||||
|
|||||||
Reference in New Issue
Block a user