I am trying to download a zip from my Apache server using NodeJS. When I try to download the zip, it downloads about 500KB of the 8MB of the zip and then just stops downloading it. The NodeJS process stays online for about a minute and then dies with the error read ETIMEDOUT
. When I try to download the same zip through the same endpoint by using my browser, it downloads it without any problem. I’ve tried to download the zip using the NodeJS script with several servers ruling out any network issue. The NodeJS script I’m using is as follows:
const axios = require('axios').default;
const path = require('path');
const fs = require('fs');
axios.get('https://example.org/endpoint.php').then(res => {
fs.writeFileSync(path.join(__dirname, `./file.zip`), res.data);
}).catch(console.log);
The endpoint is written in PHP as follows:
$zipPath = "/path/to/zip";
$filesize = filesize($zipPath);
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="file.zip"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $filesize);
flush();
readfile($zipPath);
exit();
The endpoint doesn’t send the Content-Length
header in the response, which I don’t quite understand. I have read somewhere that this might cause the NodeJS script being unable to fully download the zip, but I’m not quite sure if this is correct. I’ve tried to check whether it is the $filesize
variable causing the issue by changing the header name to X-Content-Length
, which gave me the correct output, ruling out the variable being the cause. I’ve also read somewhere that the header Transfer-Encoding: chunked
prevents me from setting the Content-Length
header. I’ve tried several solutions which helped for others, but these didn’t work for me. These are the headers the download endpoint sends:
HTTP/1.1 200 OK
Date: Wed, 24 Apr 2024 11:37:13 GMT
Server: Apache/2.4.52 (Ubuntu)
Content-Description: File Transfer
Content-Disposition: attachment; filename="file.zip"
Content-Transfer-Encoding: binary
Connection: Keep-Alive, Keep-Alive
Expires: 0
Cache-Control: must-revalidate, post-check=0, pre-check=0
Pragma: public
Upgrade: h2,h2c
Connection: Upgrade
Keep-Alive: timeout=5, max=100
Transfer-Encoding: chunked
Content-Type: application/zip
Any help would be really appreciated. Thanks.
2
Answers
It eventually appeared to be a firewall issue.
You need to pipe the response into the fileStream.
try below: