【云备份|| 日志 day6】文件业务处理模块

在这里插入图片描述

云备份day6

  • 业务处理

业务处理

云备份项目中 ,业务处理模块是针对客户端的业务请求进行处理,并最终给与响应。而整个过程中包含以下要实现的功能:

  1. 借助网络通信模块httplib库搭建http服务器与客户端进行网络通信
  2. 针对收到的请求进行对应的业务处理并进行响应(文件上传,列表查看,文件下载(包含断点续传))

业务处理模块要对客户端的请求进行处理,那么我们就需要提前定义好客户端与服务端的通信,明确客户端发送什么样的请求,服务端处理后应该给与什么样的响应,而这就是网络通信接口的设计。

HTTP文件上传:

request请求

POST /upload HTTP/1.1
Content-Length:11
Content-Type:multipart/form-data;boundary= ----WebKitFormBoundary+16字节随机字符
------WebKitFormBoundary
Content-Disposition:form-data;filename="a.txt";
hello world
------WebKitFormBoundary--

respons响应

HTTP/1.1 200 OK
Content-Length: 0

HTTP文件列表获取:

request请求

GET /list HTTP/1.1
Content-Length: 0

响应

HTTP/1.1 200 OK
Content-Length:
Content-Type: text/html

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Page of Download</title>
</head><body>
<h1>Download</h1>
<table><tr>
<td><a href="/download/a.txt"> a.txt </a></td>
<td align="right"> 1994-07-08 03:00 </td>
<td align="right"> 27K </td>
</tr></table></body>

HTTP文件下载:

请求

GET /download/a.txt http/1.1
Content-Length: 0

响应

HTTP/1.1 200 OK
Content-Length: 100000
ETags: "filename-size-mtime一个能够唯一标识文件的数据"
Accept-Ranges: bytes

服务端业务处理模块实现-业务处理类设计

extern cloud::DataManager *_data;
class Service{
private:
int _server_port;
std::string _server_ip;
std::string _url_prefix;
httplib::Server _srv;
public:
static void Upload(const httplib::Request &req, httplib::Response &rsp);
static void List(const httplib::Request &req, httplib::Response &rsp);
static void Download(const httplib::Request &req,httplib::Response &rsp);
public:
Service();
bool RunModule();
}

代码:

class Service{private:int _server_port;std::string _server_ip;std::string _download_prefix;httplib::Server _server;private:static void Upload(const httplib::Request &req, httplib::Response &rsp) {// post /upload  文件数据在正文中(正文并不全是文件数据)auto ret = req.has_file("file");//判断有没有上传的文件区域if (ret == false){rsp.status = 400;return;}const auto& file = req.get_file_value("file");//file.filename//文件名称    file.content//文件数据std::string back_dir = Config::GetInstance()->GetBackDir();std::string realpath = back_dir + FileUtil(file.filename).FileName();FileUtil fu(realpath);fu.SetContent(file.content);//将数据写入文件中;BackupInfo info;info.NewBackupInfo(realpath);//组织备份的文件信息_data->Insert(info);//向数据管理模块添加备份的文件信息return ;}static std::string TimetoStr(time_t t) {std::string tmp = std::ctime(&t);return tmp;}static void ListShow(const httplib::Request &req, httplib::Response &rsp){//1. 获取所有的文件备份信息std::vector<BackupInfo> arry;_data->GetAll(&arry);//2. 根据所有备份信息,组织html文件数据std::stringstream ss;ss << "<html><head><title>Download</title></head>";ss << "<body><h1>Download</h1><table>";for (auto &a : arry){ss << "<tr>";std::string filename = FileUtil(a.real_path).FileName();ss << "<td><a href='" << a.url << "'>" << filename << "</a></td>";ss << "<td align='right'>" << TimetoStr(a.mtime) << "</td>";ss << "<td align='right'>" << a.fsize / 1024 << "k</td>";ss << "</tr>";}ss << "</table></body></html>";rsp.body = ss.str();rsp.set_header("Content-Type", "text/html");rsp.status = 200;return ;}static std::string GetETag(const BackupInfo &info) {// etg :  filename-fsize-mtimeFileUtil fu(info.real_path);std::string etag = fu.FileName();etag += "-";etag += std::to_string(info.fsize);etag += "-";etag += std::to_string(info.mtime);return etag;}static void Download(const httplib::Request &req, httplib::Response &rsp){//1. 获取客户端请求的资源路径path   req.path//2. 根据资源路径,获取文件备份信息BackupInfo info;_data->GetOneByURL(req.path, &info);//3. 判断文件是否被压缩,如果被压缩,要先解压缩, if (info.pack_flag == true){FileUtil fu(info.pack_path);fu.UnCompress(info.real_path);//将文件解压到备份目录下//4. 删除压缩包,修改备份信息(已经没有被压缩)fu.Remove();info.pack_flag = false;_data->Update(info);}bool retrans = false;std::string old_etag;if (req.has_header("If-Range")) {old_etag = req.get_header_value("If-Range");//有If-Range字段且,这个字段的值与请求文件的最新etag一致则符合断点续传if (old_etag == GetETag(info)) {retrans = true;}}//4. 读取文件数据,放入rsp.body中FileUtil fu(info.real_path);if (retrans == false){fu.GetContent(&rsp.body);//5. 设置响应头部字段: ETag, Accept-Ranges: bytesrsp.set_header("Accept-Ranges", "bytes");rsp.set_header("ETag", GetETag(info));rsp.set_header("Content-Type", "application/octet-stream");rsp.status = 200;}else {//httplib内部实现了对于区间请求也就是断点续传请求的处理//只需要我们用户将文件所有数据读取到rsp.body中,它内部会自动根据请求//区间,从body中取出指定区间数据进行响应// std::string  range = req.get_header_val("Range"); bytes=start-endfu.GetContent(&rsp.body);rsp.set_header("Accept-Ranges", "bytes");rsp.set_header("ETag", GetETag(info));rsp.set_header("Content-Type", "application/octet-stream");//rsp.set_header("Content-Range", "bytes start-end/fsize");rsp.status = 206;//区间请求响应的是206*****}}public:Service(){Config *config = Config::GetInstance();_server_port = config->GetServerPort();_server_ip = config->GetServerIp();_download_prefix = config->GetDownloadPrefix();}bool RunModule() {_server.Post("/upload", Upload);_server.Get("/listshow", ListShow);_server.Get("/", ListShow);std::string download_url = _download_prefix + "(.*)";_server.Get(download_url, Download);_server.listen(_server_ip.c_str(), _server_port);return true;}};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/169115.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文搞懂设计模式之单例模式

大家好&#xff0c;我是晴天&#xff0c;本周我们一起来学习单例模式。本文将介绍单例模式的基本属性&#xff0c;两种构造单例的方法&#xff08;饿汉模式和懒汉模式&#xff09;以及golang自带的sync.Once()方法。 什么是单例模式 GoF对单例模式的定义是&#xff1a;保证一个…

微信小程序隐私政策不合规,应当由用户自主阅读后自行选择是否同意隐私政策协议,不得默认强制用户同意

小程序隐私政策不合规&#xff0c;默认自动同意《用户服务协议》及《隐私政策》&#xff0c;应当由用户自主阅读后自行选择是否同意隐私政策协议&#xff0c;不得默认强制用户同意&#xff0c;请整改后再重新提交。 把 登录代表同意《用户协议》和《隐私政策》 改为 同意《用…

使用迁移学习在线校准深度学习模型

使用迁移学习在线校准深度学习模型 本文参考的是2023年发表于Engineering Applications of Artificial Intelligence, EAAI的Deep Gaussian mixture adaptive network for robust soft sensor modeling with a closed-loop calibration mechanism 1. 动机 概念漂移导致历史训…

基于SSM的旅游管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Python:词法分析(行结构与显式、隐式行拼接)

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 1、逻辑结构 一个Python程序由许多逻辑行组成&#xff0c;字面意义上的一行指的是末尾有换行符(\n)&#xff0c;但在不同的情况下&#xff0c;行末尾的换行符(\n)可能有…

数据分析实战 | K-means算法——蛋白质消费特征分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 ​编辑 八、模型评价 九、模型调参与预测 一、数据及分析对象 txt文件——“protein.txt”&#xff0c;主要记录了25个国家的9个属性&#xff0c;主…

【python海洋专题四十四】海洋指数画法--多色渐变柱状图

【python海洋专题四十四】海洋指数画法–多色渐变柱状图

登录注册代码模板(Vue3+SpringBoot)[邮箱发送验证码(HTML)、RSA 加密解密(支持长文本)、黑暗与亮色主题切换、AOP信息校验]

文章归档&#xff1a;https://www.yuque.com/u27599042/coding_star/cx5ptule64utcr9e 仓库地址 https://gitee.com/tongchaowei/login-register-template 网页效果展示 相关说明 在该代码模板中&#xff0c;实现了如下功能&#xff1a; 邮箱发送验证码&#xff08;邮件内容…

C#动态拦截并覆盖第三方进程的函数,实现函数篡改(外挂)

今天在看之前收藏的一个pdf文档(介绍C#外挂的相关知识的)&#xff0c;结合网上的东西及个人的理解才有了这篇文章。 参考文章&#xff1a; 【精选】一文带解读C# 动态拦截覆盖第三方进程中的函数&#xff08;外挂必备&#xff09;_zls365365的博客-CSDN博客 DotNetDetour - …

知识蒸馏概述及开源项目推荐

文章目录 1.介绍2.知识2.1 基于响应的知识&#xff08;response-based&#xff09;2.2 基于特征的知识(feature-based)2.3 基于关系的知识(relation-based) 3.蒸馏机制3.1 离线蒸馏3.2 在线蒸馏3.3 自蒸馏 4.教师-学生架构5.蒸馏算法5.1 对抗性蒸馏&#xff08;Adversarial Dis…

vim相关命令讲解!

本文旨在讲解vim 以及其相关的操作&#xff01; 希望读完本文&#xff0c;读者会有一定的收获&#xff01;好的&#xff0c;干货马上就来&#xff01; 初识vim 在讲解vim之前&#xff0c;我们首先要了解vim是什么&#xff0c;有什么作用&#xff1f;只有了解了vim才能更好的理…

【CASS精品教程】cass3d 11.0加载超大影像、三维模型、点云数据

CAD2016+CASS11.0(内置3d)下载与安装: 【CASS精品教程】CAD2016+CASS11.0安装教程(附CASS11.0安装包下载)https://geostorm.blog.csdn.net/article/details/132392530 一、cass11.0 3d支持的数据 cass11.0中的3d模块增加了多种数据的支持,主要有: 1. 三维模型 点击…