feat: functional download server

using micro
This commit is contained in:
2019-09-27 12:16:40 -07:00
parent b66eb8abe7
commit eb35ae5dfd
7 changed files with 358 additions and 23 deletions

10
src/logger.js Normal file
View File

@@ -0,0 +1,10 @@
const pino = require('pino');
const LOG_LEVEL = process.env.NODE_ENV === 'production' ? 'info' : 'debug';
const logger = pino({
prettyPrint: process.env.NODE_ENV !== 'production',
level: LOG_LEVEL,
});
module.exports = logger;

View File

@@ -1,3 +1,94 @@
module.exports = function server() {
console.log('Server...');
const path = require('path');
const fs = require('fs');
const spawn = require('cross-spawn');
const logger = require('./logger');
const sendError = (res, code) => {
res.writeHeader(code);
res.write(code === 400 ? 'Bad Request' : 'Internal Server Error');
res.end();
};
module.exports = async function server(req, res) {
let sent = false;
let filename;
const { url, format } = req.queryParams;
logger.debug(`Request: ${req.url}`);
if (!url) {
sendError(res, 400);
return;
}
const dataPath = path.resolve(__dirname, '../data');
const params = [url];
if (format) {
params.unshift(format);
params.unshift('--format');
}
logger.info(`Downloading ${url}`);
const proc = spawn('youtube-dl', params, {
stdio: 'pipe',
cwd: dataPath,
});
proc.stdout.on('data', data => {
const match = data.toString().match(/\[download\] Destination: (.+)/i);
const existsMatch = data.toString().match(/\[download\] (.+) has already been downloaded/i);
if (match !== null) {
// eslint-disable-next-line prefer-destructuring
filename = match[1];
} else if (existsMatch !== null) {
// eslint-disable-next-line prefer-destructuring
filename = existsMatch[1];
}
});
proc.on('error', err => {
logger.error(err);
logger.info(`child process exited with code ${err.code}`);
if (!sent) {
sendError(res, 500);
sent = true;
}
});
proc.on('close', code => {
logger.info(`child process exited with code ${code}`);
if (!filename) {
logger.error('Failed to capture download filename');
sendError(res, 500);
sent = true;
return;
}
const dlFilepath = path.join(__dirname, '../data', filename);
logger.debug(`Downloaded file is ${dlFilepath}`);
if (!sent) {
fs.readFile(dlFilepath, (err, fileBuffer) => {
if (err) {
sendError(res, 500);
sent = true;
return;
}
res.writeHead(200, {
'Content-Type': 'application/octet-stream',
'Content-Length': fileBuffer.length,
'Content-disposition': `attachment; filename=${filename}`,
});
res.write(fileBuffer);
res.end();
sent = true;
});
}
sent = true;
});
};