【项目】Rust开发的完全私人图床服务器

原文约3600字,阅读约需9分钟。发表于:

私人图床搭建 Github仓库 1、目标: 安全性:使用HTTPS进行加密。 私密性:完全自我管理的存储。 独创性:尽可能自行编写代码。 2、整体方案 上传流程: 显示流程: PC上运行一个图床web服务器,提供上传和下载功能。 3、图床服务器源码 use axum::{ extract::{Multipart, Path}, routing::get, routing::post, Json, Router, }; use hyper::{Body, Response, StatusCode}; // use multipart::server::Multipart; use std::{ net::SocketAddr, path::{self}, }; use tokio::fs; // use tokio_stream::wrappers::BytesStream; use serde::{Deserialize, Serialize}; use uuid::Uuid; async fn serve_image(Path(filename): Path<String>) -> Result<Response<Body>, String> { if filename.find("..").is_some() || filename.find("/").is_some() { return Ok(hyper::Response::builder() .status(StatusCode::NOT_FOUND) .body(Body::from("Not Found")) .unwrap() .into()); } if filename.find(".png").is_none() { return Ok(hyper::Response::builder() .status(StatusCode::NOT_FOUND) .body(Body::from("Not Found")) .unwrap() .into()); } let path = format!("uploads/{}", filename); if let Ok(data) = fs::read(&path).await { Ok(hyper::Response::new(Body::from(data))) } else { Ok(hyper::Response::builder() .status(StatusCode::NOT_FOUND) .body(Body::from("Not Found")) .unwrap() .into()) } } #[derive(Debug, Deserialize, Serialize)] struct UploadResp { dst: String, } #[derive(Debug, Deserialize, Serialize)] struct UploadReq { file: String, } async fn upload(data: String) -> Result<Json<UploadResp>, StatusCode> { let data: UploadReq = serde_json::from_str(&data).map_err(|_| StatusCode::BAD_REQUEST)?; let data = base64::decode(data.file).map_err(|_| StatusCode::BAD_REQUEST)?; let base_path = std::path::Path::new("uploads"); if !base_path.exists() { fs::create_dir(base_path).await.unwrap(); } let file_name = format!("{}.png", Uuid::new_v4()); // let filename = format!("uploads/1.png"); fs::write(&base_path.join(&file_name), data).await.unwrap(); Ok(Json(UploadResp { dst: format!( "https://img.example.com:444/{}", // 主意!!!!这儿修改为你的服务器域名和端口 base_path.join(&file_name).to_string_lossy() ), })) } #[tokio::main] async fn main() { // std::env::set_var("RUST_LOG", "trace"); env_logger::init(); let app = Router::new() .route("/upload", post(upload)) .route("/uploads/:filename", get(serve_image)); let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); println!("Listening on http://{}", addr); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } /upload:使用POST方法,供upic上传图片。 /uploads:使用GET方法,获取图片数据。 4、部署 4.1 在vps上 设置frp实现内网穿透, a、下载frp wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_arm64.tar.gz tar -xvzf ./frp_0.51.3_linux_arm64.tar.gz b、修改配置文件 vim frps.ini 配置为: [common] bind_port = 7000 # 密码,修改为自己的 token = 123456 # https端口 vhost_https_port = 444 c、后台运行frp服务端 nohup ./frps -c frps.ini & 4.2 PC上 a、下载frp wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_arm64.tar.gz tar -xvzf ./frp_0.51.3_linux_arm64.tar.gz b、修改客户端配置文件 vim frpc.ini 配置为: [common] # vps 公网ip server_addr = 1.1.1.1 server_port = 7000 # 密码 token = 123456 # 端口,与服务器保持一致 vhost_https_port = 444 [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000 [test_https2http] type = https # 域名 custom_domains = img.example.com plugin = https2http # 图床服务器的端口,如果没修改源码,默认不用改 plugin_local_addr = 127.0.0.1:3000 # https证书,自行搜索如何获取https证书 plugin_crt_path = ./server.crt plugin_key_path = ./server.key plugin_host_header_rewrite = 127.0.0.1 plugin_header_X-From-Where = frp c、后台运行frp客户端 nohup ./frpc -c frpc.ini & d、运行图床http服务器 nohup ./img_server & 4.4 upic设置 添加一个自定义的图床: 只需修改域名部分。完成设置后,可以进行验证,如果一切正常,将返回一个URL链接。 更多教程欢迎关注我的博客

本文介绍了搭建私人图床服务器的步骤,包括获取源码、实现上传和下载功能、在VPS和PC上的部署、配置内网穿透和frp客户端,以及在upic中添加自定义图床。

【项目】Rust开发的完全私人图床服务器
相关推荐 去reddit讨论