Skip to content

Axios leaks streams when it does not fully read them #3770

@misos1

Description

@misos1

Describe the bug

In certain situations axios leaves the input stream in an unfinished state which leads to leaks.

To Reproduce

There are 3 variations which can be switched using the variation variable:

Variation 0: Server does not read request body but immediately sends empty response.
Variation 1: Server destroys request which causes EPIPE error from axios (or similar).
Variation 2: Server fully reads request body before sending empty response. Axios has body length limiting enabled.

let variation = 0;

let fs = require("fs");
let posix = require("posix");
let axios = require("axios");
let server = require("express")();

posix.setrlimit("nofile", { soft: 1000 });

fs.writeFileSync("file", Buffer.alloc(10000000));

server.put("/", async function(req, res)
{
	if(variation == 0) res.end();
	if(variation == 1) req.destroy();
	if(variation == 2)
	{
		for await (let chunk of req);
		res.end();
	}
});

(async function()
{
	await new Promise(resolve => server.listen(8080, resolve));
	for(let i = 0; ; i++)
	{
		console.log(i);
		let stream = fs.createReadStream("file");
		let prom;
		if(variation == 0) prom = axios.put("http://127.0.0.1:8080", stream, { maxRedirects: 0 });
		if(variation == 1) prom = axios.put("http://127.0.0.1:8080", stream, { maxRedirects: 0 });
		if(variation == 2) prom = axios.put("http://127.0.0.1:8080", stream, { maxBodyLength: 100 });
		await prom.catch(e => { if(e.code == "EMFILE") throw e; });
	}
}());

All 3 variations produces output like this:

976
(node:100644) UnhandledPromiseRejectionWarning: Error: connect EMFILE 127.0.0.1:8080 - Local (undefined:undefined)
    at internalConnect (net.js:921:16)
    at defaultTriggerAsyncIdScope (internal/async_hooks.js:430:12)
    at net.js:1009:9
    at processTicksAndRejections (internal/process/task_queues.js:75:11)

Expected behavior

No EMFILE.

Environment

  • Axios Version 0.21.1
  • Adapter HTTP
  • Node.js Version v14.16.0 and v15.12.0

Additional context/Screenshots

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions