• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Rust Web 全栈开发 - 2 HTTP请求

武飞扬头像
shiyivei
帮助1

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);
    }
 }
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcieha
系列文章
更多 icon
同类精品
更多 icon
继续加载