mdf bouncer safe
This commit is contained in:
parent
32a2c63a4e
commit
bac4e5d8c6
1 changed files with 38 additions and 7 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
use std::{env::{args, var}, io, sync::Arc};
|
use std::{env::{args, var}, io, sync::Arc};
|
||||||
|
|
||||||
use axum::{Router, body::{Body, Bytes}, extract::{DefaultBodyLimit, Path, State}, routing::{delete, post, put}};
|
use axum::{Router, body::{Body, Bytes}, extract::{DefaultBodyLimit, Path, State}, http::StatusCode, routing::{delete, post, put}};
|
||||||
|
use log::info;
|
||||||
|
use tokio::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
const MAXIMUM_PACKET_SIZE: usize = (2 << 20) * 10;
|
const MAXIMUM_PACKET_SIZE: usize = (2 << 20) * 10;
|
||||||
|
|
@ -12,6 +14,7 @@ struct AppState {
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> io::Result<()> {
|
async fn main() -> io::Result<()> {
|
||||||
|
pretty_env_logger::init();
|
||||||
// get secret from secret file
|
// get secret from secret file
|
||||||
let mut args = args().skip(1);
|
let mut args = args().skip(1);
|
||||||
let target_path = args.next().expect("need to specify target path");
|
let target_path = args.next().expect("need to specify target path");
|
||||||
|
|
@ -39,13 +42,41 @@ async fn main() -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn delete_file(State(state): State<Arc<AppState>>, Path(path): Path<String>) {
|
async fn delete_file(State(state): State<Arc<AppState>>, Path(path): Path<String>) -> Result<StatusCode, StatusCode> {
|
||||||
println!("about to delete: {path}");
|
let full_path = safe_join(&state.root, &path)?;
|
||||||
|
info!("about to delete: {:?}", full_path);
|
||||||
|
|
||||||
|
fs::remove_file(full_path)
|
||||||
|
.await
|
||||||
|
.map_err(|_| StatusCode::NOT_FOUND)?;
|
||||||
|
|
||||||
|
Ok(StatusCode::NO_CONTENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn put_file(State(state): State<Arc<AppState>>, Path(path): Path<String>, body: Bytes) {
|
async fn put_file(State(state): State<Arc<AppState>>, Path(path): Path<String>, body: Bytes) -> Result<StatusCode, StatusCode> {
|
||||||
println!("about to put: {path}");
|
let full_path = safe_join(&state.root, &path)?;
|
||||||
let bytes = Vec::from(body);
|
info!("about to put: {:?}", full_path);
|
||||||
println!("body: {:?}", bytes);
|
|
||||||
|
if let Some(parent) = full_path.parent() {
|
||||||
|
fs::create_dir_all(parent).await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||||
|
}
|
||||||
|
fs::write(full_path, body)
|
||||||
|
.await
|
||||||
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||||
|
|
||||||
|
Ok(StatusCode::CREATED)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Make supplied path does not contain anything other than relative
|
||||||
|
/// paths.
|
||||||
|
fn safe_join(base: &PathBuf, user_path: &str) -> Result<PathBuf, StatusCode> {
|
||||||
|
let mut full = base.clone();
|
||||||
|
let path = PathBuf::from(user_path);
|
||||||
|
for comp in path.components() {
|
||||||
|
match comp {
|
||||||
|
std::path::Component::Normal(p) => full.push(p),
|
||||||
|
_ => return Err(StatusCode::BAD_REQUEST),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(full)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue