Rust 自建HTTP Server支持图片响应

这篇具有很好参考价值的文章主要介绍了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 trait
        write_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拆分出来发送。文章来源地址https://www.toymoban.com/news/detail-498021.html

到了这里,关于Rust 自建HTTP Server支持图片响应的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第1章. 为什么要自建博客

    博客,仅音译,英文名为 Blogger ,为Web Log的混成词。它的正式名称为网络日记;又音译为部落格或部落阁等,是使用特定的软件,在网络上出版、发表和张贴个人文章的人,或者是一种通常由个人管理、不定期张贴新的文章的网站。它是一种网络交流方式,是网络时代的个人

    2023年04月25日
    浏览(36)
  • 前端本地原生开发好用的 http server 服务(npm 包形式、支持热更新、简单好用)

    有时候在本地原生网页开发的时候,需要起一个服务能够直接访问当现在正在开发 index.html 等内容,也就是希望通过 npm 包在进入项目文件夹后,直接可以起一个 可访问的 http 链接 ,不希望在去安装 nginx 。 下面例举几个: serve:为本地静态页面创建一个可访问的服务,不支

    2024年02月04日
    浏览(58)
  • 基于 ESP32 创建 HTTP Server 服务器,支持载入文件到服务器,并对载入文件进行删除管理

    软件编程指南参见:HTTP 服务器 任意一款 ESP32 系列开发板 2.4GHz 路由器热点 准备各种格式的文件 可基于 esp-idf/examples/protocols/http_server /file_serving 例程进行测试 只需要设置 ESP32 连接的 2.4GHz 的 WiFi 热点 即可 menuconfig — Example Connection Configuration — WiFi SSID — WiFi Password 下载固件

    2024年02月16日
    浏览(58)
  • SQL Server(解决问题)已成功与服务器建立连接,但是在登录过程中发生错误

    SQL Server(解决问题)已成功与服务器建立连接,但是在登录过程中发生错误。provider: Shared Memory Provider, error:0 - 管道的另一端上无任何进程。我们将 身份验证 选择为 SQL Server 身份验证。输入刚刚创建的用户名和密码: 但是现在还是不能直接使用,因为权限问题。你会看到下

    2024年02月06日
    浏览(47)
  • SQL Server :已成功与服务器建立连接,但是在登录前的握手期间发生错误。

    学习sqlserver的时候,默认的身份验证是windows的身份验证。 而在进一步学习的时候希望改成sqlserver的身份验证。操作流程无非就是选中服务器——》右击属性 再按如下图选择,当然sqlserver有默认的身份验证账号,sa,操作教程也有,这里不谈。我也是按如此操作的 当然我画蛇

    2024年02月07日
    浏览(51)
  • 微信小程序post传递参数为formData格式,一般是在上传图片时需要的

    wx.uploadFile传参的格式本身就是formData格式的,参照官网就可以 如果是wx.request的需要formData格式,如下图data的格式

    2024年02月13日
    浏览(53)
  • 【uniapp】微信小程序,取视频第一帧,前提是 图片是在 阿里云的oss上

    上传视频等,默认为黑色,无法用视频的第一帧作为封面,以及视频的video为原生组件,层级很高无法覆盖问题,虽然有cover-view,但很多场景还是不灵活 自己服务器是不支持的 ,可以用canvas截图 方法 ,将 图片组件image 替换成 视频video 组件 视频组件video 重点 将video组件更换

    2024年02月08日
    浏览(46)
  • 幻兽帕鲁:自建多人联机服务器,支持32人联机

     Steam游戏《幻兽帕鲁》是新上线的一款开服世界生存制作游戏,上线短短5天时间,就卖出了700万份,同时在线人数最高达到180万人,创下了Steam历史榜单第二名的好成绩。预期之外的爆火使幻兽帕鲁官方服务器正面临大量玩家涌入而导致的服务器网络拥堵问题,很多玩家反馈

    2024年02月20日
    浏览(50)
  • windows自建免费无限的开源图片识别公式转换为Latex

    python3.9.6下载 在最开始勾选添加环境变量 https://www.python.org/ftp/python/3.9.6/python-3.9.6-amd64.exe 验证,右键终端(管理员),输入:python --version 安装Anaconda https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-5.3.1-Windows-x86_64.exe 运行安装包,一路默认路径就ok 配置环境变量 ,主要添加\\\"C:Pr

    2023年04月16日
    浏览(40)
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载

    (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载 带后台系统PbootCMS内核开发的网站模板,该模板适用于新闻博客网站、自媒体运营网站等企业,当然其他行业也可以做,只需要把文字图片换成其他行业的即可; 自适应手机端,同一个后台,

    2024年02月05日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包