Rust 自建HTTP Server支持图片响应
本博客是在杨旭老师的 rust web 全栈教程项目基础上进行修改,支持了图片资源返回,杨旭老师的rust web链接如下:
https://www.bilibili.com/video/BV1RP4y1G7KFp=1&vd_source=8595fbbf160cc11a0cc07cadacf22951
本人默认读者已经学习了相关基础教程和杨旭老师的相关课程,直接开始针对项目里面对应文件进行修改说明。
一、新增加载图片资源方法
在原先项目加载文件方法同一层,新增支持加载图片资源如下。
pub trait Handler{fn handle(res:&HttpRequest) ->HttpResponse;fn load_file(file_name:&str) ->Option<Vec<u8>>{println!("load_file file_name={}",file_name);let default_path = format!("{}/public",env!("CARGO_MANIFEST_DIR"));println!("load_file default_path={}",default_path);let public_path = env::var("PUBLIC_PATH").unwrap_or(default_path);let full_path = format!("{}/{}",public_path,file_name);println!("load_file full_path={}",full_path);let contents = fs::read(full_path);contents.ok()}fn load_image(image_name:&str) ->Option<Vec<u8>>{let default_path = format!("{}/public",env!("CARGO_MANIFEST_DIR"));let public_path = env::var("PUBLIC_PATH").unwrap_or(default_path);let full_path = format!("{}/{}/{}",public_path,"image",image_name);println!("load_image full_path={}",full_path);let contents: Result<Vec<u8>, std::io::Error> = fs::read(full_path);contents.ok()}
}
load_image 方法就是本博客新增方法,根据入参图片名称,去指定public目录下image文件夹下读取图片文件,返回Vec<u8> 字节流。
我们在旧的新增了图片处理分支如下
impl Handler for StaticPageHandler{fn handle(req:&HttpRequest) ->HttpResponse{let http::httprequest::Resource::Path(s) =&req.resourece;let route:Vec<&str> = s.split("/").collect();println!("route={}",route[1]);if route[1]=="image" {match Self::load_image(route[2]){Some(content) => {let mut map:HashMap<&str,&str> = HashMap::new();map.insert("Content-Type","image/webp");println!("读取到文件长度{}",content.len());return HttpResponse::new("200",Some(map),Some(content));},None => {return HttpResponse::new("404",None,Self::load_file("404.html"))}}}match route[1] {"" =>HttpResponse::new("200",None,Self::load_file("index.html")),"health" =>HttpResponse::new("200",None,Self::load_file("health.html")),path => match Self::load_file(path) {Some(contents) =>{let mut map:HashMap<&str,&str> = HashMap::new();if path.ends_with(".css") {map.insert("Content-Type","text/css");}else if path.ends_with(".js") {map.insert("Content-Type","text/javascript");}else {map.insert("Content-Type","text/html");}HttpResponse::new("200",Some(map),Some(contents))},None => HttpResponse::new("404",None,Self::load_file("404.html"))}}}
}
特别说明点根据加载图片类型不同,map.insert("Content-Type","image/webp");
这里的Content-Type也要对应修改,我这里返回的文件是webp格式。
二、修改HttpResponse 结构体body数据类型
旧项目中由于返回的都是文本内容,body数据类型定义成字符串切片,由于这次改动读取图片是字节流,所以这里的body也需要变更成Option<Vec<u8>>类型
#[derive(Debug,PartialEq,Clone)]
pub struct HttpResponse<'a>{version:&'a str,status_code:&'a str,status_text:&'a str,header:Option<HashMap<&'a str,&'a str>>,body:Option<Vec<u8>>,
}
三、修改HttpResponse 响应方法
上面已经提到了,旧项目返回的是文本内容,故在发送HttpResponse数据是,直接将数据转化成字符串发送。这里我们为了兼容图片资源的响应,所以body为Vec<u8>类型时就不适用先前的方法。我们对除了body字段,其他字段依然按照旧的逻辑转化成字符串。
impl <'a> From<HttpResponse<'a>> for String{fn from(res:HttpResponse) -> String{let res1 = res.clone();format!("{} {} {}\r\n{}Content-Length:{}\r\n\r\n",&res1.version(),&res1.status_code(),&res1.status_text(),&res1.header(),&res.body.unwrap().len(),)}
}
相比较旧的方法,我们去掉了body参数。
四、返回body数据
上面讲过了,我们在响应转String时,将body数据拆分出来了,那么通过什么方法返回body数据。
pub fn send_response(&self, write_stream:&mut impl Write) -> Result<(),std::io::Error>{let res = self.clone();let response_string: String = String::from(res); // from traitwrite_stream.write(response_string.as_bytes()).unwrap();write_stream.write(&self.body()).unwrap();write_stream.flush().unwrap();Ok(())}
我们就是通过write_stream.write(&self.body()).unwrap();将body数据再独立发送一下。
整理上来讲改动很小,就是将body数据类型从&str,改成了Vec<u8>,在发送响应时将body拆分出来发送。
相关文章:

Rust 自建HTTP Server支持图片响应
本博客是在杨旭老师的 rust web 全栈教程项目基础上进行修改,支持了图片资源返回,杨旭老师的rust web链接如下: https://www.bilibili.com/video/BV1RP4y1G7KFp1&vd_source8595fbbf160cc11a0cc07cadacf22951 本人默认读者已经学习了相关…...

[游戏开发][Unity]UnityWebRequest使用大全
首先记录个小问题 使用new UnityWebRequest的方式,最终的downloadHandler是个null 使用UnityWebRequest.Get的方式,最终的downloadHandler会是DownloadHandlerBuffer 从网站或本地下载内容,包括文本或二进制数据 IEnumerator downloadfile(st…...

如何使用Fiddler对手机进行弱网测试?(干货教程)
1.首先,fiddler连接手机 1)Tools->Options->Connections->设置端口8888,勾选Allow remote computers to connect 2)配置手机 注:手机和电脑需要在同一局域网下 手机进入网络详情,将代理改为手动 设置主机名、端口 主机…...

专业科普:什么是单片机?
一、什么是单片机 单片机诞生于20世纪70年代末,它是指一个集成在一块芯片上的完整计算机系统。单片机具有一个完整计算机所需要的大部分部件:CPU、内存、内部和外部总线系统,目前大部分还会具有外存。同时集成诸如通讯接口、定时器ÿ…...

深度学习-第T11周——优化器对比实验
深度学习-第T11周——优化器对比实验 深度学习-第T11周——优化器对比实验一、前言二、我的环境三、前期工作1、导入数据集2、查看图片数目3、查看数据 四、数据预处理1、 加载数据1、设置图片格式2、划分训练集3、划分验证集4、查看标签 2、数据可视化3、检查数据4、配置数据集…...

基于Dlib的疲劳检测系统
需要源码的朋友可以私信我 基于Dlib的疲劳检测系统 1、设计背景及要求2、系统分析3、系统设计3.1功能结构图3.2基于EAR、MAR和HPE算法的疲劳检测3.2.1基于EAR算法的眨眼检测3.2.2基于MAR算法的哈欠检测3.3.3基于HPE算法的点头检测 4、系统实现与调试4.1初步实现4.2具体实现过程…...

three.js通过CubeTexture加载环境贴图,和RGBELoader加载器加载hdr环境贴图
一、使用CubeTexture进行环境贴图 1.CubeTexture使用介绍 Three.js中可以通过使用CubeTexture进行环境贴图,CubeTexture需要将6张图片(正面、反面、上下左右)包装成一个立方体纹理。下面是一个简单的例子: 首先需要加载六张贴图…...

pycharm中Terminal输入sqlite3,出现无法将sqlite项识别为cmdlet**的解决方法
前提:本机上已安装sqlite3,安装详见:pycharm社区版中安装配置sqlite3_Sunshine_0426的博客-CSDN博客 问题: cmd命令行中或pycharm中Terminal行输入sqlite3 db.sqlite3命令后,出现“无法将“sqlite3”项识别为 cmdlet…...

VSCode 安装配置教程详解包含c++环境配置方法
vscode安装教程及c环境配置详解 vscode下载安装下载C扩展插件VScode C环境配置配置环境变量检查 MinGW 安装配置编译器:配置构建任务检查是否安装了编译器配置完毕 vscode下载安装 地址:官网下载地址 直接打开下载好的.exe文件进行安装即可࿰…...

Baumer工业相机堡盟工业相机如何通过BGAPISDK将图像放大缩小显示(C#)
Baumer工业相机堡盟工业相机如何通过BGAPISDK将图像放大缩小显示(C#) Baumer工业相机Baumer工业相机BGAPISDK和图像放大缩小的技术背景Baumer工业相机通过BGAPISDK将相机图像图像放大缩小功能1.引用合适的类文件2.通过BGAPISDK将相机图像图像放大缩小功能…...

8.1 PowerBI系列之DAX函数专题-进阶-解决列排序对计算的影响
需求 下列矩阵中,在月份列不按照原始数据的month_no排列时,能正确计算销售额占比,但是当月份按照month_no排序时就会出错,需要解决这个问题。 实现 month % divide([amount],calculate([amount],all(date[month desc]))) //排…...

Java的第十二篇文章——集合
目录 第十二章 集合 学习目标 1. 集合框架的由来 2. 集合框架的继承体系 3. Collection接口 3.1 Collection接口的常用方法 4. Iterator接口 4.1 Iterator接口的抽象方法 4.2 获取迭代器接口实现类 4.3 迭代器的实现原理 4.4 并发修改异常 4.5 集合存储自定义对象并…...

docker 镜像制作 与 CI/CD
目录 镜像到底是什么? 使用docker创建镜像 步骤: 1、编辑Dockerfile(Dockerfile是docker制作镜像的配方文件) 2、编辑requirements.txt文件 3、编辑app.py文件,我们的程序文件 4、生成镜像文件 5、查看生成的镜…...

Spring Boot 异常报告器解析
基于Spring Boot 3.1.0 系列文章 Spring Boot 源码阅读初始化环境搭建Spring Boot 框架整体启动流程详解Spring Boot 系统初始化器详解Spring Boot 监听器详解Spring Boot banner详解Spring Boot 属性配置解析Spring Boot 属性加载原理解析Spring Boot 异常报告器解析 创建自定…...

瑞亚太空活动公司RSA与英国国防与安全加速器达成量子项目合作
(图片来源:网络) 瑞亚太空活动公司(RSA)与英国国防与安全加速器(DASA)签署了合作协议,主要开发名为“无限交换”的可操纵量子真空的技术项目。这是RSA在英国签订的第一份合同&…...

Shapley值法介绍及实例计算
Shapley值法介绍及实例计算 为解决多个局中人在合作过程中因利益分配而产生矛盾的问题,属于合作博弈领域。应用 Shapley 值的一大优势是按照成员对联盟的边际贡献率将利益进行分配,即成员 i 所分得的利益等于该成员为他所参与联盟创造的边际利益的平均值…...

不用手动改 package.json 的版本号
“为什么package.json 里的版本还是原来的,有没有更新?”,这个时候我意识到,我们完全没有必要在每次发布的时候还特意去关注这个仓库的版本号,只要在发布打tag的时候同步一下即可 node.js 部分,我们得有一个…...

gitlab Can‘t update,dev has no tracked branch
代码仓库迁移到gitlab后本地更改仓库地址后 拉取代码报错: Can’t update,dev has no tracked branch: 解决办法: 在当前项目的目录下运行命令: git branch -u git dev --set-upstream-toorigin/dev第一个dev是本地分支名字&…...

sql批量操作
SQl: 1,在某一字段后批量增加内容:UPDATE 表名 SET 字段 CONCAT(字段,要增加的内容) 例:UPDATE b8_niuniu_permission SET game_ids CONCAT(game_ids,,3) (或者后面可以加where条件) 2,批量修改某一字段…...

数据库监控与调优【九】—— 索引数据结构
索引数据结构-B-Tree索引、Hash索引、空间索引、全文索引 二叉树查找 对于相同深度的节点,左侧的节点总是比右侧的节点小。在搜索时,如果要搜索的值key大于根节点(图中6),就会在右侧子树里查找;key小于根…...

哈工大计算机网络传输层详解之:流水线机制与滑动窗口协议
哈工大计算机网络传输层详解之:流水线机制与滑动窗口协议 哈工大计算机网络课程传输层协议详解之:可靠数据传输的基本原理哈工大计算机网络课程传输层协议详解之:TCP协议哈工大计算机网络课程传输层协议详解之:拥塞控制原理剖析 …...

Unity Mac最新打苹果包流程
作者介绍:铸梦xy。IT公司技术合伙人,IT高级讲师,资深Unity架构师,铸梦之路系列课程创始人。 IOS详细打包流程1.申请APPID2.申请开发证书3.创建描述文件 IOS详细打包流程 1.申请AppID 2.创建证书 3.申请配置文件(又名描…...

【MySQL数据库 | 第二十篇】explain执行计划
目录 前言: explain: 语法: 总结: 前言: 上一篇我们介绍了从时间角度分析MySQL语句执行效率的三大工具:SQL执行频率,慢日志查询,profile。但是这三个方法也只是在时间角度粗略的…...

学Python能做哪些副业?我一般不告诉别人!建议存好
前两天一个朋友找到我吐槽,说工资一发交完房租水电,啥也不剩,搞不懂朋友圈里那些天天吃喝玩乐的同龄人钱都是哪来的?确实如此,刚毕业的大学生工资起薪都很低,在高消费、高租金的城市,别说存钱&a…...

简化 Hello World:Java 新写法要来了
OpenJDK 的 JEP 445 提案正在努力简化 Java 的入门难度。 这个提案主要是引入 “灵活的 Main 方法和匿名 Main 类” ,希望 Java 的学习过程能更平滑,让学生和初学者能更好地接受 Java 。 提案的作者 Ron Pressler 解释:现在的 Java 语言非常…...

【服务器】springboot实现HTTP服务监听
文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…...

浅谈常见的加密算法及实现
浅谈常见的加密算法及实现 简介: 随着公司业务的发展,系统用户量日益增多,系统安全性问题一直在脑子里反复回旋,以前系统用户少影响面小,安全方面也一直没有进行思考和加固,现如今业务发展了,虽…...

FTP协议详解
简介 FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协…...

网络安全|渗透测试入门学习,从零基础入门到精通—渗透中的开发语言
目录 前面的话 开发语言 1、html 解析 2、JavaScript 用法 3、JAVA 特性 4、PHP 作用 PHP 能做什么? 5、C/C 使用 如何学习 前面的话 关于在渗透中需要学习的语言第一点个人认为就是可以打一下HTML,JS那些基础知识,磨刀不误砍柴…...

八大排序算法之归并排序(递归实现+非递归实现)
目录 一.归并排序的基本思想 归并排序算法思想(排升序为例) 二.两个有序子序列(同一个数组中)的归并(排升序) 两个有序序列归并操作代码: 三.归并排序的递归实现 递归归并排序的实现:(后序遍历递归) 递归函数抽象分析: 四.非递归归并排序的实现 1.非递归归并排序算法…...