十七、单线程 Web 服务器

本文将详细介绍如何使用 Rust 开发功能完善的单线程 Web 服务器。

1. 创建项目

cargo new single-threaded-web
cd single-threaded-web

2. 项目结构

single-threaded-web/
├── Cargo.toml
├── src/
│   ├── main.rs      # 服务器入口
│   ├── lib.rs       # 核心实现
│   └── http/        # HTTP协议相关
│       ├── mod.rs   # 模块定义
│       ├── request.rs # 请求解析
│       └── response.rs # 响应构建
├── static/          # 静态文件
│   ├── index.html   # 示例页面
│   └── 404.html     # 404页面

3. 编辑Cargo.toml

[package]
name = "single-threaded-web"
version = "0.1.0"
edition = "2024"

[dependencies]
thiserror = "1.0"    # 错误处理
bytes = "1.0"        # 字节处理
httparse = "1.8"     # HTTP解析
log = "0.4"          # 日志
env_logger = "0.10"  # 日志实现

4. 实现HTTP模块 (src/http/mod.rs)

mod request;
mod response;

// 导出所有公共类型
pub use request::{Request, Method};
pub use response::{Response, StatusCode};

/// HTTP相关错误
#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Invalid HTTP request")]
    InvalidRequest,
    
    #[error("I/O error: {0}")]
    Io(#[from] std::io::Error),
    
    #[error("Unsupported HTTP method")]
    UnsupportedMethod,
    
    #[error("Invalid HTTP header")]
    InvalidHeader,
    
    #[error("HTTP parse error: {0}")]
    Parse(#[from] httparse::Error),
}

5. 实现请求解析 (src/http/request.rs)

use std::collections::HashMap;
use std::str::FromStr;
use crate::http::Error;

/// HTTP请求方法
#[derive(Debug, PartialEq)]
pub enum Method {
    GET,
    POST,
}

impl std::fmt::Display for Method {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Method::GET => write!(f, "GET"),
            Method::POST => write!(f, "POST"),
        }
    }
}

impl FromStr for Method {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "GET" => Ok(Method::GET),
            "POST" => Ok(Method::POST),
            _ => Err(Error::UnsupportedMethod),
        }
    }
}

/// HTTP请求
#[derive(Debug)]
pub struct Request {
    pub method: Method,
    pub path: String,
    pub headers: HashMap<String, String>,
    pub body: Vec<u8>,
}

impl Request {
    /// 从字节流解析HTTP请求
    pub fn parse(buffer: &[u8]) -> Result<Self, Error> {
        let mut headers = [httparse::EMPTY_HEADER; 16];
        let mut req = httparse::Request::new(&mut headers);
        
        let status = req.parse(buffer).map_err(Error::from)?;
        
        if status.is_partial() {
            return Err(Error::InvalidRequest);
        }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a736015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值