feat: add pingora-demo

This commit is contained in:
2025-08-17 15:50:54 +08:00
parent a1024943ff
commit 3dda4e8e5b
5 changed files with 3010 additions and 1 deletions

2908
__network/pingora-demo/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
[package]
name = "pingora-demo"
version = "0.1.0"
edition = "2024"
[dependencies]
pingora-core = "0.2"
pingora-proxy = "0.2"
tokio = { version = "1.0", features = ["full"] }
async-trait = "0.1"
mime_guess = "2.0"
headers = "0.3"

View File

@@ -0,0 +1,6 @@
> Copied from: https://mp.weixin.qq.com/s/RHSy2EeK3XTRYXtOSCO0Ug
> https://play.hatter.me/doc/showDocDetail.jssp?id=8495

View File

@@ -0,0 +1,80 @@
use async_trait::async_trait;
use headers::{ContentLength, ContentType};
use pingora_core::server::Server;
use pingora_proxy::{ProxyHttp, Session};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use mime_guess::from_path;
struct StaticFileServer {
root_dir: PathBuf,
}
impl StaticFileServer {
fn new(root: impl AsRef<Path>) -> Self {
StaticFileServer {
root_dir: root.as_ref().to_path_buf(),
}
}
}
#[async_trait]
impl ProxyHttp for StaticFileServer {
async fn response_filter(&self, session: &mut Session, response: &mut pingora_http::Response) {
let path = session.req_header().uri.path();
let file_path = self.root_dir.join(&path[1..]); // 去除前导/
if let Ok(metadata) = tokio::fs::metadata(&file_path).await {
if metadata.is_file() {
if let Ok(file) = tokio::fs::read(&file_path).await {
// 设置正确的Content-Type
let mime = from_path(&file_path).first_or_octet_stream();
response.headers_mut().insert(
headers::CONTENT_TYPE,
ContentType::from(mime).to_string().parse().unwrap(),
);
// 设置Content-Length
response.headers_mut().insert(
headers::CONTENT_LENGTH,
ContentLength(metadata.len()).to_string().parse().unwrap(),
);
// 设置缓存头CDN关键配置
response.headers_mut().insert(
"cache-control",
"public, max-age=31536000".parse().unwrap(), // 1年缓存
);
*response.body_mut() = file.into();
response.set_status(200);
return;
}
}
}
// 文件不存在
*response.status_mut() = 404;
*response.body_mut() = b"Not Found".to_vec().into();
}
}
#[tokio::main]
async fn main() {
// 1. 初始化服务器
let mut server = Server::new(Some("Static File Server")).unwrap();
server.bootstrap();
// 2. 创建文件服务(假设静态文件在./static目录
let static_service = StaticFileServer::new("./static");
let mut service = pingora_proxy::http_proxy_service(&server.configuration, static_service);
// 3. 监听端口
service.add_tcp("0.0.0.0:8080");
// 4. 启动服务
server.add_service(service);
println!("Static file server running on :8080");
server.run_forever();
}