Skip to content

Commit

Permalink
1.1.0 添加http代理工具 优化一些操作
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaobaidadada committed Jan 8, 2025
1 parent 8902836 commit 196bd85
Show file tree
Hide file tree
Showing 52 changed files with 1,005 additions and 146 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ url: http://116.198.245.137:5569/
6. 终端,默认是bash, windwos下是 powershell。
7. 超大文本日志查看器,对任意大小的文本右键使用作为日志类型查看,点击窗口后可以使用上下键来快速滚动翻页,还可以实时输出内容。
- ssh代理,ftp代理: 可以管理多个linux服务器,作用和winscp类似,让终端和文件管理更方便。
- http代理,类似postman 的发送http请求功能
- 网站,是网址收藏夹,可用于保存服务器上其它的网站
- ddns
- http网页代理、rdp代理(windwos远程控制)、rtsp代理播放器,输入直播源,比如监控的url可以实时网页观看
Expand Down
2 changes: 1 addition & 1 deletion src/common/FileMenuType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class FileMenuData {
items?:{r?:string,v?:any}[];
files?:any;
dir?:string;
call?:()=>void;
call?:(e?:any)=>void;
ok?:any;
dockerId?:string;
name?:string;
Expand Down
9 changes: 9 additions & 0 deletions src/common/StringUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,13 @@ export function generateSaltyUUID(context: string= "") {
result += characters[randomIndex];
}
return result;
}

export function generateRandomHash(length = 16) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let hash = '';
for (let i = 0; i < length; i++) {
hash += characters.charAt(Math.floor(Math.random() * characters.length));
}
return hash;
}
33 changes: 33 additions & 0 deletions src/common/req/net.pojo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,36 @@ export class VirNetItem {
real_ip:string;
online:boolean = false;
}


export interface HttpFormData {
key: string;
value: string; // 值如果是文件 这个值没有意义
// 下面是有文件的时候才有意义的
is_file?: boolean;
fullPath?: string; // 临时名字
fileName?: string; // 实际名字
file_object?: any // 临时的 服务端不保存

}
export enum http_body_type {
row = 1,
json = 2,
form = 3,

}
export class HttpFormPojo {
body_type:http_body_type;
header_type:number; // 1 请求头 2 请求体
url:string;
method:string;
headers:any;
// 字符串数据
data:string;
// json 数据
json_data:string;
// 表单数据
// form_data:{[key:string]:HttpFormData} | string;
form_data_list :HttpFormData[] | string;

}
13 changes: 12 additions & 1 deletion src/main/domain/data/DataUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import fse from 'fs-extra'
import {Env} from "../../../common/Env";
export enum file_key {
data = "data",
systemd = "systemd"
systemd = "systemd",
http_tag = "http_tag",
}
export enum data_dir_tem_name {
tempfile = "tempfile", // 临时文件
http_tempfile = "http_tempfile", // http 请求的临时文件
}
export class DataUtil {
private static data_path_map = {};
Expand All @@ -13,6 +18,12 @@ export class DataUtil {
// private static data_path = "";
// private static data = {};

public static get_tem_path(type:data_dir_tem_name) {
const p = path.join(Env.work_dir, type);
fse.ensureDirSync(p)
return p;
}

private static init(file:file_key) {
let value = this.data_path_map[file];
if (value === undefined || value=== null) {
Expand Down
5 changes: 3 additions & 2 deletions src/main/domain/file/file.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export class FileController {

@Get('/:path([^"]{0,})')
async getFile(@Req() ctx, @Param("path") path?: string, @QueryParam("is_sys_path", {required: false}) is_sys_path?: number): Promise<Result<GetFilePojo | string>> {
return await FileServiceImpl.getFile(path, ctx.headers.authorization, is_sys_path);
// 默认已经对 url 解码了 这里不做也行
return await FileServiceImpl.getFile(decodeURIComponent(path), ctx.headers.authorization, is_sys_path);
}

@Post('/file/info')
Expand All @@ -57,7 +58,7 @@ export class FileController {

@Put('/:path([^"]{0,})')
async uploadFile(@Req() req: Request, @Res() res: Response, @Param("path") path?: string) {
await FileServiceImpl.uploadFile(path, req, res, req.headers.authorization);
await FileServiceImpl.uploadFile(decodeURIComponent(path), req, res, req.headers.authorization);
return Sucess("1");
}

Expand Down
1 change: 1 addition & 0 deletions src/main/domain/file/file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ class FileService extends FileCompress {
})
};

// 上传文件 必须 保证文件所在的文件夹已经存在了
upload = multer({
storage: this.fileUploadOptions.storage,
// limits: { fileSize: 1024 * 1024 * 2 }, // 限制文件大小为 2MB 无限制
Expand Down
26 changes: 24 additions & 2 deletions src/main/domain/net/net.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Body, Controller, Get, JsonController, Post} from "routing-controllers";
import {Body, Controller, Get, JsonController, Param, Post, Put, Req, Res} from "routing-controllers";
import {UserLogin} from "../../../common/req/user.req";
import {AuthFail, Fail, Sucess} from "../../other/Result";
import {Cache} from "../../other/cache";
Expand All @@ -8,14 +8,19 @@ import {CmdType, WsData} from "../../../common/frame/WsData";
import {NetPojo, VirClientPojo, VirNetItem, VirServerPojo} from "../../../common/req/net.pojo";
import {netService} from "./net.service";
import {NavIndexItem} from "../../../common/req/common.pojo";
import {DataUtil} from "../data/DataUtil";
import {DataUtil, file_key} from "../data/DataUtil";
import {virtualService} from "./net.virtual.service";
import {Wss} from "../../../common/frame/ws.server";
import {Request, Response} from "express";
import {FileServiceImpl} from "../file/file.service";

const navindex_key = "navindex_net_key_list";

const navindex_wol_key = "navindex_wol_key";

const http_tag_key = "http_tag_key";


@JsonController("/net")
export class NetController {

Expand Down Expand Up @@ -92,4 +97,21 @@ export class NetController {
return list;
}

// http 的tag
@Get("/http/tag")
get_http_tag() {
let list = DataUtil.get(http_tag_key,file_key.http_tag);
return Sucess(list || []);
}

@Post('/http/tag/save')
save_http_tag(@Body() items: NavIndexItem[]) {
DataUtil.set(http_tag_key, items,file_key.http_tag);
return Sucess('ok');
}

@Post('/http/send')
async httpSend(@Req() req: Request, @Res() res: Response) {
return netService.httpSend(req, res);
}
}
110 changes: 108 additions & 2 deletions src/main/domain/net/net.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import {NetPojo} from "../../../common/req/net.pojo";
import {http_body_type, HttpFormData, HttpFormPojo, NetPojo} from "../../../common/req/net.pojo";
import {findAvailablePort} from "../../../common/findPort";
import {Sucess} from "../../other/Result";
import {Fail, Sucess} from "../../other/Result";
import proxy from 'koa-proxies';
import {Request, Response} from "express";
import path from "path";
import fs from "fs";
import multer from 'multer';
import {data_dir_tem_name, DataUtil} from "../data/DataUtil";

const needle = require('needle');


const Koa = require('koa');
const cors = require('@koa/cors');
Expand Down Expand Up @@ -137,6 +145,104 @@ export class NetService {
socket.close();
});
}

fileUploadOptions = {
storage: multer.diskStorage({
destination: (req: any, file: any, cb: any) => {
// return cb(new Error("Custom error: Path issue"));
cb(null, req.fileDir); // 存储路径
},
filename: (req: any, file: any, cb: any) => {
// file.originalname
cb(null, file.fieldname);
}
})
};
upload = multer({
storage: this.fileUploadOptions.storage,
// limits: { fileSize: 1024 * 1024 * 2 }, // 限制文件大小为 2MB 无限制
}).any();

public httpSend(req: Request, res: Response) {

const sysPath = path.join(DataUtil.get_tem_path(data_dir_tem_name.http_tempfile));
req['fileDir'] = sysPath;
// req['fileName'] = path.basename(sysPath);
return new Promise((resolve)=>{
this.upload(req, res, (err) => {
// console.log(req)
if (err) {
resolve(res.status(500).send(Fail(err.message)));
return;
}
const pojo = JSON.parse(req.body.data) as HttpFormPojo;
const call = (err, needle_res) => {
if (err) {
console.error('Error:', err);
resolve(res.status(500).send(err.code));
} else {
resolve(res.header('filecat_remote_raw_headers',needle_res.rawHeaders).status(needle_res.statusCode).send(needle_res.raw));
}
if(pojo.form_data_list) {
for(const item of pojo.form_data_list as HttpFormData[]) {
try {
if(item.is_file) {
fs.unlinkSync(path.join(sysPath,item.fullPath))
}
} catch (e) {
console.log(e)
}
}
}

};
const option = {
headers:pojo.headers
};
try {
if (pojo.body_type === http_body_type.json) {
pojo.data = pojo.json_data;
}
switch (pojo.method) {
case 'get':
needle(pojo.method,pojo.url,option, call);
break;
case 'put':
case 'post': {
if (pojo.form_data_list) {
option['multipart'] = true;
const form = {};
const files = {};
for (const f of req['files'] ?? []) {
files[f['fieldname']] = f;
}
for(const item of pojo.form_data_list as HttpFormData[]) {
if(item.is_file) {
form[item.key] = {
file:path.join(sysPath,item.fullPath) ,
filename: item.fileName,
content_type: files[item.fullPath]?.mimetype
};
} else {
form[item.key] = item.value;
}
}
needle[pojo.method](pojo.url,form,option, call);
} else {
needle[pojo.method](pojo.url,pojo.data,option, call);
}
}
break;
default:
needle[pojo.method](pojo.url,pojo.data,option, call);
break;
}
} catch (e) {
resolve(res.status(500).send(e.message));
}
});
})
}
}

export const netService: NetService = new NetService();
2 changes: 1 addition & 1 deletion src/main/domain/ssh/ssh.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export class SshService extends SshSsh2 {
public async uploadFile(req:any,res:Response) {
const client = this.lifeGetData(SshPojo.getKey(req.query)) as Client;
const sftp = this.sftGet(client);
const remoteFilePath = req.query.target;
const remoteFilePath = decodeURIComponent(req.query.target);
if (req.query.dir === "1") {
req.dir = remoteFilePath;
await this.sftCreateDir(req, client);
Expand Down
Loading

0 comments on commit 196bd85

Please sign in to comment.