#web-apps #web-framework #web-server #applications #internet #dynamic #milstian

milstian-internet-framework

我用Rust实现的一个轻量级和动态互联网应用程序框架的第一次实验

10个版本

使用旧Rust 2015

0.3.1 2019年3月13日
0.3.0 2018年10月13日
0.2.2 2018年10月12日
0.1.4 2018年10月2日
0.1.3 2018年9月25日

#1075 in HTTP服务器

31 每月下载量

GPL-3.0-only

235KB
1.5K SLoC

Milstian - 一个Rust互联网框架

Milstian Logo

正在进行中,主要用于学习Rust编程。

此项目基于《Rust编程语言》一书中的编程练习《构建多线程Web服务器》(Starch Press 2018)以及受到《Aomebo Web Framework for PHP》的启发。

主要目标

  • 用它轻松制作可扩展、快速且健壮的任何类型的网站

目标

  • 支持通过TCP/IP进行HTTP和HTTPS的并发互联网服务器
  • 集成Web应用程序框架
  • 易于为任何类型的应用程序进行定制
  • 快速
  • 可扩展
  • 灵活
  • 可能支持其他传输协议和应用层协议

开发

  • 在所有Rust文件上使用rust-fmt
  • 使用cargo checkcargo test确保有效性

运行本地服务器

  • 访问项目存储库根目录
  • 运行cargo run --example static localhost 8888 10 index.htm ./html/ 404.htm 1024

参数是

  • TCP主机名
  • TCP端口
  • 工作进程限制
  • HTTP目录索引文件
  • HTTP web服务器文件系统根目录
  • HTTP未找到文件
  • 最大TCP请求大小

示例静态TCP-HTTP应用程序

extern crate milstian_internet_framework;
use milstian_internet_framework::{Application, Config};

fn main() {
    let config = Config::from_env().expect("Failed to get configuration from environment");
    Application::new(config).tcp_http_with_legacy_responders();
}

示例简单动态TCP-HTTP应用程序

extern crate milstian_internet_framework;

use std::collections::HashMap;
use std::net::SocketAddr;
use milstian_internet_framework::request;
use milstian_internet_framework::response;
use milstian_internet_framework::response::tcp::http::ResponderInterface;
use milstian_internet_framework::{Application, Config};

#[derive(Clone)]
pub struct Responder {
    pub route: Option<String>,
}

impl Responder {
    pub fn new() -> Responder {
        Responder { route: None }
    }
}

impl ResponderInterface for Responder {
    fn matches(
        &mut self,
        request_message: &request::Message,
        _application: &Application,
        _socket: &SocketAddr,
        _overflow_bytes: &u8,
    ) -> bool {
        match request_message.request_line.query_arguments.get("test") {
            Some(value) => {
                self.route = Some(value.clone());
                return true;
            }
            None => {
                return false;
            }
        }
    }

    fn respond(
        &self,
        request_message: &request::Message,
        _application: &Application,
        _socket: &SocketAddr,
        _overflow_bytes: &u8,
    ) -> Result<Vec<u8>, String> {
        if let Some(route) = &self.route {
            let protocol =
                request::Message::get_protocol_text(&request_message.request_line.protocol);
            let mut headers: HashMap<String, String> = HashMap::new();
            headers.insert("Content-Type".to_string(), "text/plain".to_string());
            return Ok(response::Message::new(
                protocol.to_string(),
                "200 OK".to_string(),
                headers,
                format!("Was here: {}", route).as_bytes().to_vec(),
            ).to_bytes());
        } else {
            Err("No result".to_string())
        }
    }
}

fn main() {
    let config = Config::from_env().expect("Failed to get configuration from environment");
    Application::new(config).tcp_http_with_legacy_and_custom_responders(Box::new(Responder::new()));
}

文档

许可证

本项目受HTTP服务器

依赖关系

~1.5MB
~19K SLoC