代码拉取完成,页面将自动刷新
/* eslint-disable no-console */
const express = require('express');
const spdy = require('spdy');
const multer = require('multer');
const fs = require('fs-extra');
const path = require('path');
const {createClient} = require('redis');
const {mergeFile, getFileExtName} = require('./util');
const {
SERVER_KEY_PATH,
SERVER_CERT_PATH,
FILE_FOLDER,
FILES_HASH_KEY,
CLIENT_ERROR_CODE,
SERVER_ERROR_CODE,
PARTIAL_CONTENT_CODE,
PORT
} = require('./config');
const upload = multer().any();
const app = express();
app.use(express.json());
const redisClient = createClient();
// 错误处理中间件
const errorHandler = (err, req, res, next) => {
console.error(err.stack);
res.status(SERVER_ERROR_CODE).send({msg: err.message});
};
// 计算请求耗时的中间件
const requestTimeMiddleware = (req, res, next) => {
const startTime = Date.now();
next(); // 继续传递请求到下一个中间件或路由处理函数
res.on('close', () => {
const endTime = Date.now();
const elapsedTime = endTime - startTime;
console.log(
`Request to ${req.method} ${req.url} took ${elapsedTime} ms`
);
});
};
app.use(requestTimeMiddleware);
app.use(express.static(__dirname + '/output'));
// 获取上传的文件
app.get('/file/:name', async (req, res) => {
const file = path.resolve(__dirname, FILE_FOLDER, req.params.name);
const fileExists = await fs.exists(file);
if (!fileExists) {
return res.status(CLIENT_ERROR_CODE).send({msg: '该文件不存在'});
}
const readStream = fs.createReadStream(file);
return readStream.pipe(res);
});
app.post('/speed-test',express.raw({ type: 'application/octet-stream', limit: '1000mb' }), (req, res) => {
console.log('-------------开始测试----------------', req.body)
res.send('ok');
})
// 上传分片文件
app.post('/upload', (req, res, next) => {
upload(req, res, async err => {
if (err) {
return next(err);
}
const {chunkName, hash, chunkHash} = req.body;
const exists = await redisClient.sIsMember(hash, chunkHash);
const filename = path.resolve(__dirname, FILE_FOLDER, chunkName);
if (exists) {
const fileExist = await fs.exists(filename);
if (!fileExist) {
fs.writeFile(filename, req.files[0].buffer); // 解决不同分片hash相同的问题
}
return res.status(PARTIAL_CONTENT_CODE).send({msg: chunkName + '已经存在'});
}
try {
await Promise.all([
fs.writeFile(filename, req.files[0].buffer),
redisClient.sAdd(hash, chunkHash)
]);
} catch (err) {
return next(err);
}
return res.status(PARTIAL_CONTENT_CODE).send(chunkName + '上传完毕');
});
});
// 合并文件
app.post('/merge', async (req, res, next) => {
const {filename, length, hash} = req.body;
const extName = getFileExtName(filename);
const exists = await redisClient.sIsMember(FILES_HASH_KEY, hash);
if (exists) {
return res.status(CLIENT_ERROR_CODE).send({
msg: '文件已存在!',
fileURL: `/file/${hash}.${extName}`
});
}
try {
await mergeFile({filename, length, hash, outputFolder: FILE_FOLDER});
await Promise.all([
redisClient.del(hash), // 删除所有分片hash
redisClient.sAdd(FILES_HASH_KEY, hash) // 存储已上传的文件hash
]);
} catch (err) {
return next(err);
}
return res.send({fileURL: `/file/${hash}.${extName}`});
});
// 上传前根据hash check改文件是否存在
app.post('/check', async (req, res) => {
// 目录不存在,创建目录
const dirExists = await fs.pathExists(path.resolve(__dirname, FILE_FOLDER));
if (!dirExists) {
fs.mkdir(path.resolve(__dirname, FILE_FOLDER));
}
const {hash, fileName} = req.body;
const exits = await redisClient.sIsMember(FILES_HASH_KEY, hash);
if (exits) {
const extName = getFileExtName(fileName);
return res.send({
fileURL: `/file/${hash}.${extName}`,
exits
});
}
return res.send({exits});
});
// 连接redis
(async () => {
await redisClient.connect();
redisClient.on('error', err => console.log('Redis Client Error', err));
})();
const server = spdy.createServer(
{
key: fs.readFileSync(SERVER_KEY_PATH),
cert: fs.readFileSync(SERVER_CERT_PATH)
},
app
);
function bindingToPort(port) {
server.listen(port, err => {
if (err) {
console.log('error on binding port: ' + port);
return;
}
console.log(`Server is running on https://localhost:${port}`);
});
server.on('error', err => {
if (err.code === 'EADDRINUSE') {
server.close(() => {
bindingToPort(port + 1);
});
} else {
console.log('error ', err);
}
});
}
app.use(errorHandler);
// 启动服务
bindingToPort(PORT);
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。