关于扫毒代码实现展示
官方网址:
病毒库官方下载文档(clamav)
项目代码:远程方法实现扫毒功能
Container.clanscan = async function (file) {
const passthrough = new PassThrough();
const ClamScan = await new NodeClam().init({
clamdscan: {
host: '10.37.36.22',
port: 3310,
}
});
var flag = false;
try {
// You can re-use the `clamscan` object as many times as you want
let upStream = fs.createReadStream(file);
upStream.pipe(passthrough);
const { is_infected, viruses } = await ClamScan.scan_stream(passthrough);
if (is_infected) {
console.log('error');
// 刪除目錄
fs.unlinkSync(file);
// 返回錯誤訊息
} else {
flag = true;
console.log(flag);
console.log('OK~~');
}
return flag;
} catch (err) {
// Handle any errors raised by the code in the try block
}
}
};
**json配置:**
{
"name": "Container",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {},
"acls": [],
"methods": {
"clanscan": {
"accepts": [
{
"arg": "file",
"type": "string"
}
],
"returns": {
"type": "boolean",
"root": true
},
"description": "",
"http": {
"path": "/clanscan",
"verb": "post"
}
}
}
}
远程call api调用clanscan 方法
'use strict';
const request = require('request')
module.exports = function (Container) {
Container.afterRemote('upload', async function (ctx, unused, next) {
const app = Container.app;
var files = ctx.result.result.files.files;
var data = ctx.result.result.fields;
//服务器文件路径
let fPath = `/armstrong/dfi/api/dfi/server/storage/${files[0].container}/${files[0].name}`;
let result = await getDataByApi(fPath);
console.log(result.body);
return result.body;
});
async function getDataByApi(fPath) {
let headers = {
'content-type': 'application/json'
};
let fileObject = { file: fPath };
let url = "http://10.37.36.22:13017/api/Containers/clanscan";
let payload = {
headers: headers,
url: url,
body: JSON.stringify(fileObject)
};
return new Promise((resolve, reject) => {
request.post(payload, (error, body) => {
if (error) {
console.log(error);
} else {
resolve(body);
}
});
});
}
};
如果使用socket,需要本地连接病毒库clamsan,没法使用远程
const clamscan = await new NodeClam().init({
debug_mode: false,
clamdscan: {
bypass_test: true,
host: '127.0.0.1',
port: 3310,
socket: '/var/lib/clamav/clamd.sock',
},
});
代码遇到的知识总结
一、nodejs中http,request,response使用总结
https://blog.csdn.net/qq_26239917/article/details/90214885
request使用
async function getDataByApi(fPath) {
let headers = {
'content-type': 'application/json'
};
let fileObject = { file: fPath };
let url = "http://10.37.36.22:13017/api/Containers/clanscan";
let payload = {
headers: headers,
url: url,
body: JSON.stringify(fileObject)
};
return new Promise((resolve, reject) => {
request.post(payload, (error, body) => {
if (error) {
console.log(error);
} else {
resolve(body);
}
});
});
}
知识重点
body: JSON.stringify(fileObject)作为参数,body参数值必须是一个对象
原因:需要重新启动一下项目
http知识总结(不知如何传递参数)
二、es6中同异步总结
async函数
async函数返回一个promise对象,可以使用then方法添加回调函数。当函数执行的时候。一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。(也就是所返回的是promise对象,要不用then来回调要不用await来获得返回的值)
await命令
1. 正常情况下,await命令后面是一个promise对象。如果不是,会被转成一个立即resolve的Promise对象。
比如:async function f(){return await 123}
f().then(v => console.log(v) //123
2.await命令后面的Promise对象如果变为reject状态(整个async函数都会中断执行),则reject的参数会被catch方法的回调函数接受到,
比如:async function f(){ await Promise.reject('出错了’)}
f().then(v =>console.log(v)
.catch(e =>console.log(e) //出错了
async函数返回的是promise对象,await是等待Promise执行完成并得到结果状态
promise对象
有三种状态:Pending(进行中)、Fulfill(已成功)和Rejected(已失败)
then代码块的值无法带出
ClamScan.then(async clamscan => {
try {
// You can re-use the `clamscan` object as many times as you want
let upStream = fs.createReadStream(file);
upStream.pipe(passthrough);
const { is_infected, viruses } = await ClamScan.scan_stream(passthrough);
if (is_infected) {
console.log('error');
// 刪除目錄
fs.unlinkSync(file);
// 返回錯誤訊息
} else {
flag = true;
console.log(flag); //**这里的值为true**
console.log('OK~~');
}
return flag; //**这里的值无法返回到外部**
} catch (err) {
// Handle any errors raised by the code in the try block
}
});
三、fs和文件流总结
四、node-module总结(文件)
五、git知识总结
六、文件上传loopback总结
“root”: “./server/storage”
loopback-component-starage@^3.5.0版本是相对路径而3.7版本是绝对路径也就是node- module的路径。则使用3.5.0,“root”: "./server/storage"才是正确的
h_ttps://github.com/jheinnic/randomArt/blob/c6a8ade5afffb37182a6ca535bb545871f5e4f96/common/models/artwork.js
https://github.com/theblockchainu/blockchainu-api-server/blob/a648c84996e20ade21ab74a91d366ae6ee90013b/common/models/media.js
loopback官网
1. "storage": {
"name": "storage",
"connector": "loopback-component-storage",
"provider": "filesystem",
"root": "./server/storage",
"maxFileSize": "50000000"
},
2. "container": {
"dataSource": "storage",
"public": true
}
3.创建server/storage文件夹
七、ngnx方向代理总结
ngnx方向代理
八、package-lock(相关依赖)知识总结
- 因为npm是一个用于管理package之间依赖关系的管理器,它允许开发者在pacakge.json中间标出自己项目对npm各库包的依赖。你可以选择以如下方式来标明自己所需要库包的版本;例如:
“dependencies”: {
“@types/node”: “^8.0.33”,
},
这里面的 向上标号^是定义了向后(新)兼容依赖,指如果 types/node的版本是超过8.0.33,并在大版本号(8)上相同,就允许下载最新版本的 types/node库包,例如实际上可能运行npm install时候下载的具体版本是8.0.35。npm install xxx@x.x.x 这样去更新我们的依赖。
当在 install dependency 的指定版本时,会自动更新 package-lock.json 文件中该 dependency 的 version 到指定的 version
当在 install dependency 的范围版本时,当前的 version 低于or等于 package-lock.json 文件中对应的 dependency 的 version 时,会安装 package-lock.json 中的 version;
package.json
“antd”: “^3.6.1”, // eg:最新版本是 3.9.4
package-lock.json
“antd”: “3.7.1”,
执行npm install 会安装 3.7.1 版本
如果高于 package-lock.json 中对应的 dependency 的 version 时,会安装当前范围版本号中最高的版本,会更新 package-lock.json 文件中对应的版本号;
九、trigger触发器
CREATE DEFINER=`dfq`@`%` TRIGGER `NPICHECKLIST_EM_HEAD_after_insert` AFTER UPDATE ON `NPICHECKLIST_EM_HEAD` FOR EACH ROW BEGIN
IF OLD.SIGNSTATUS = 1 AND NEW.SIGNSTATUS = 2 THEN
INSERT INTO dfi.Mail(sender, receiver, subject, content)
SELECT 'DFi@wistron.com' AS sender,
NPITEAMMEMBERLIST.EMAIL AS receiver,
'DFi Exit Meeting Notice' AS subject,
CONCAT(
'Dear Sir/ Madam:<br/>The C4/C5 exit check list is waiting for your approve.',
'<br/>Bg:', NPIMODEL.BG,
'<br/>Bu:', NPIMODEL.BU,
'<br/>Site:', NPITEAMMEMBERHEAD.SITE,
'<br/>Plant:', NPITEAMMEMBERHEAD.PLANT,
'<br/>Customer:', NPIMODEL.CUSTOMER,
'<br/>Model:', NPIMODEL.MODEL,
'<br/>Stage:', NEW.STAGE,
'<br/>Link <a href = "http://dfi.wks.wistron.com.cn/dashboard/dfq/exit-meeting/meeting-review?bg=', NPIMODEL.BG, '&bu=', NPIMODEL.BU, '&site=', NPITEAMMEMBERHEAD.SITE, '&plant=', NPITEAMMEMBERHEAD.PLANT, '&customer=', NPIMODEL.CUSTOMER, '&model=', NPIMODEL.MODEL, '&stage=', NEW.STAGE, '">DFQ C4/C5 system</a>')
AS content
FROM NPITEAMMEMBERHEAD
JOIN NPITEAMMEMBERLIST ON NPITEAMMEMBERLIST.LISTID = NPITEAMMEMBERHEAD.LISTID AND NPITEAMMEMBERLIST.SITE = NPITEAMMEMBERHEAD.SITE
JOIN NPIMODEL ON NPIMODEL.SITE = NPITEAMMEMBERHEAD.SITE AND NPIMODEL.PLANT = NPITEAMMEMBERHEAD.PLANT AND NPIMODEL.MODEL = NPITEAMMEMBERHEAD.MODEL
WHERE NPITEAMMEMBERHEAD.SITE = NEW.SITE AND
NPITEAMMEMBERHEAD.PLANT=NEW.PLANT AND
NPITEAMMEMBERHEAD.MODEL=NEW.MODEL AND
NPITEAMMEMBERLIST.ROLE='CFE';
END IF;
END
知识总结
CREATE TRIGGER trigger_name
trigger_time
trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
其中:
trigger_name:标识触发器名称,用户自行指定;
trigger_time:标识触发时机,取值为 BEFORE 或 AFTER;
trigger_event:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
tbl_name:标识建立触发器的表名,即在哪张表上建立触发器;
trigger_stmt:触发器程序体,可以是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句。
十、loopback权限
如果声明模型没有外键属性,则LoopBack将添加具有相同名称的属性。该属性的类 型将与目标模型的id 属性的类型相同(belongs to 目标模型)
十一、postman使用详细使用方法