IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Rust Web 全栈开发 - 2 解析HTTP请求 -> 正文阅读

[网络协议]Rust Web 全栈开发 - 2 解析HTTP请求

2. 解析HTTP请求

需要定义三个数据结构

构建两个package,并且在根目录下的toml文件中将这两个package加进去

cargo new httpserver
cargo new --lib http

声明一个模块

/Users/qinjianquan/s1/http/src/lib.rs

pub mod httprequest;

再在如下文件夹中创建两个文件

/Users/qinjianquan/s1/http/src

httprequest.rs

httpresponse.rs

然后在继续编写代码

/Users/qinjianquan/s1/http/src/httprequest.rs

use std::collections::HashMap;


#[derive(Debug,PartialEq)]
//1.method
pub enum Method {
    Get,
    Post,
    Uninitialized,
}

//为枚举实现方法
impl From<&str> for Method {
     fn from(s:&str) -> Method {
         match s {
             "GET" =>Method::Get,
             "POST"=>Method::Post,
             _ => Method::Uninitialized,
         }
    }
}

//2.version
#[derive(Debug,PartialEq)]
pub enum Version {
    V1_1,
    V2_0,
    Uninitialized,
}

impl From<&str> for Version {
    fn from(s:&str) ->Version{
         match s {
             "HTTP/1.1" => Version::V1_1,
             _ => Version::Uninitialized,
         }
    }
}

//3.resource
#[derive(Debug,PartialEq)]
pub enum Resource {
    Path(String),
}


#[derive(Debug)]
pub struct HttpRequest  {
    pub method: Method, 
    pub version: Version,
    pub resource: Resource,
    pub headers: HashMap<String,String>,
    pub msg_body: String,
}

impl From<String> for HttpRequest {
    fn from(req:String) -> Self {
         let mut parsed_method = Method::Uninitialized;
         let mut parsed_version = Version::V1_1;
         let mut parsed_resource = Resource::Path("".to_string());
         let mut parsed_headers = HashMap::new();
         let mut parsed_msg_body = "";

         for line in req.lines() {
              if line.contains("HTTP") {
                   let (method,resource,version) = process_req_line(line);
                   parsed_method =method;
                   parsed_resource = resource;
                   parsed_version= version;
              }else if line.contains(":"){
                   let(key,value) = process_header_line(line);
                   parsed_headers.insert(key,value);
              }else if line.len() == 0 {
                   
              }else {
                   parsed_msg_body = line;
              }
         }
         HttpRequest { 
              method: parsed_method, 
              version: parsed_version, 
              resource: parsed_resource, 
              headers: parsed_headers, 
              msg_body: parsed_msg_body.to_string(),
          }
    }
}


fn process_req_line(s: &str) -> (Method,Resource,Version) {
    let mut words = s.split_whitespace();
   
    let method = words.next().unwrap();
    let resource = words.next().unwrap();
    let version = words.next().unwrap();
    
    (
        method.into(),
        Resource::Path(resource.to_string()),
        version.into(),
    )
}
fn process_header_line(s:&str) -> (String,String){
    let mut header_items = s.split(":");
    let mut key = String::from("");
    let mut value = String::from("");
    if let Some(k) = header_items.next(){
        key = k.to_string();
    }
    if let Some(v) = header_items.next(){
        value = v.to_string();
    }

    (key,value)
}



//测试方法

#[cfg(test)]

mod tests {

    use super::*;

    #[test]

    fn test_method_into() {
        let m: Method = "GET".into();
        assert_eq!(m,Method::Get);
    }

    #[test]

    fn test_version_into() {
         let v: Version = "HTTP/1.1".into();
         assert_eq!(v,Version::V1_1);
    }

    #[test]

    fn test_read_http () {
        let s:String = String::from("GET /greeting HTTP/1.1\r\nHost:localhost:3000\r\nUser-Agent:curl/7.71.1\r\nAccept:*/*\r\n\r\n");
        let mut headers_expexted = HashMap::new();
        headers_expexted.insert("Host".into(), "localhost".into());
        headers_expexted.insert("Accept".into(), "*/*".into());
        headers_expexted.insert("User-Agent".into(), "curl/7.71.1".into());

        let req: HttpRequest = s.into();

        assert_eq!(Method::Get,req.method);
        assert_eq!(Version::V1_1,req.version);
        assert_eq!(Resource::Path("/greeting".to_string()),req.resource);
        assert_eq!(headers_expexted,req.headers);
    }
 }
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:30:35  更:2022-04-01 00:31:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:58:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码