当前位置: 首页 > news >正文

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 全栈教程项目基础上进行修改&#xff0c;支持了图片资源返回&#xff0c;杨旭老师的rust web链接如下&#xff1a; https://www.bilibili.com/video/BV1RP4y1G7KFp1&vd_source8595fbbf160cc11a0cc07cadacf22951 本人默认读者已经学习了相关…...

[游戏开发][Unity]UnityWebRequest使用大全

首先记录个小问题 使用new UnityWebRequest的方式&#xff0c;最终的downloadHandler是个null 使用UnityWebRequest.Get的方式&#xff0c;最终的downloadHandler会是DownloadHandlerBuffer 从网站或本地下载内容&#xff0c;包括文本或二进制数据 IEnumerator downloadfile(st…...

如何使用Fiddler对手机进行弱网测试?(干货教程)

1.首先&#xff0c;fiddler连接手机 1)Tools->Options->Connections->设置端口8888&#xff0c;勾选Allow remote computers to connect 2)配置手机 注&#xff1a;手机和电脑需要在同一局域网下 手机进入网络详情&#xff0c;将代理改为手动 设置主机名、端口 主机…...

专业科普:什么是单片机?

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

深度学习-第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进行环境贴图&#xff0c;CubeTexture需要将6张图片&#xff08;正面、反面、上下左右&#xff09;包装成一个立方体纹理。下面是一个简单的例子&#xff1a; 首先需要加载六张贴图…...

pycharm中Terminal输入sqlite3,出现无法将sqlite项识别为cmdlet**的解决方法

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

VSCode 安装配置教程详解包含c++环境配置方法

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

Baumer工业相机堡盟工业相机如何通过BGAPISDK将图像放大缩小显示(C#)

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

8.1 PowerBI系列之DAX函数专题-进阶-解决列排序对计算的影响

需求 下列矩阵中&#xff0c;在月份列不按照原始数据的month_no排列时&#xff0c;能正确计算销售额占比&#xff0c;但是当月份按照month_no排序时就会出错&#xff0c;需要解决这个问题。 实现 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

目录 镜像到底是什么&#xff1f; 使用docker创建镜像 步骤&#xff1a; 1、编辑Dockerfile&#xff08;Dockerfile是docker制作镜像的配方文件&#xff09; 2、编辑requirements.txt文件 3、编辑app.py文件&#xff0c;我们的程序文件 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与英国国防与安全加速器达成量子项目合作

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

Shapley值法介绍及实例计算

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

不用手动改 package.json 的版本号

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

gitlab Can‘t update,dev has no tracked branch

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

sql批量操作

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

数据库监控与调优【九】—— 索引数据结构

索引数据结构-B-Tree索引、Hash索引、空间索引、全文索引 二叉树查找 对于相同深度的节点&#xff0c;左侧的节点总是比右侧的节点小。在搜索时&#xff0c;如果要搜索的值key大于根节点&#xff08;图中6&#xff09;&#xff0c;就会在右侧子树里查找&#xff1b;key小于根…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...