we hav haz lua
This commit is contained in:
1049
Cargo.lock
generated
1049
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ opt-level = "z"
|
|||||||
file-format = "0.24"
|
file-format = "0.24"
|
||||||
axum = { version = "0.7", features = [] }
|
axum = { version = "0.7", features = [] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
tera = { version = "1.19", features = [] }
|
tera = { version = "1.19", features = [] }
|
||||||
tokio = { version = "1.37", features = ["full"] }
|
tokio = { version = "1.37", features = ["full"] }
|
||||||
tokio-stream = { version = "0.1", features = ["full"] }
|
tokio-stream = { version = "0.1", features = ["full"] }
|
||||||
@@ -24,3 +25,11 @@ exe = "0.5"
|
|||||||
image = { version = "0.25", features = ["ico"] }
|
image = { version = "0.25", features = ["ico"] }
|
||||||
urlencoding = "2.1"
|
urlencoding = "2.1"
|
||||||
markdown = "1.0.0-alpha.16"
|
markdown = "1.0.0-alpha.16"
|
||||||
|
mlua = { version = "0.9", features = [
|
||||||
|
"lua54",
|
||||||
|
"vendored",
|
||||||
|
"serialize",
|
||||||
|
"async",
|
||||||
|
"send",
|
||||||
|
] }
|
||||||
|
reqwest = { version = "0.10", features = ["json", "rustls-tls", "blocking"] }
|
||||||
|
182
src/main.rs
182
src/main.rs
@@ -3,12 +3,13 @@ mod icon;
|
|||||||
use std::{collections::HashMap, fs, io::ErrorKind, path::PathBuf, str::FromStr};
|
use std::{collections::HashMap, fs, io::ErrorKind, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
use icon::extract_icon;
|
use icon::extract_icon;
|
||||||
|
use mlua::{Lua, Table, Value as LuaValue};
|
||||||
use once_cell::sync::{Lazy, OnceCell};
|
use once_cell::sync::{Lazy, OnceCell};
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::Request,
|
extract::Request,
|
||||||
handler::HandlerWithoutStateExt,
|
handler::HandlerWithoutStateExt,
|
||||||
http::StatusCode,
|
http::{HeaderName, HeaderValue, StatusCode},
|
||||||
response::{Html, IntoResponse},
|
response::{Html, IntoResponse},
|
||||||
routing::get,
|
routing::get,
|
||||||
};
|
};
|
||||||
@@ -177,8 +178,6 @@ async fn file_handler(request: Request) -> impl IntoResponse {
|
|||||||
PathBuf::from_str(&std::env::var("BASE_DIR").unwrap_or(String::from("./public"))).unwrap()
|
PathBuf::from_str(&std::env::var("BASE_DIR").unwrap_or(String::from("./public"))).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
dbg!(&request);
|
|
||||||
|
|
||||||
if !request.uri().path().ends_with(".lua") {
|
if !request.uri().path().ends_with(".lua") {
|
||||||
return ServeDir::new(base_dir)
|
return ServeDir::new(base_dir)
|
||||||
.fallback(get(handler))
|
.fallback(get(handler))
|
||||||
@@ -188,12 +187,179 @@ async fn file_handler(request: Request) -> impl IntoResponse {
|
|||||||
.map_err(|_| StatusCode::NOT_FOUND);
|
.map_err(|_| StatusCode::NOT_FOUND);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: process file as lua, where everything "printed" and or "returned" from the file is presented on screen
|
let lua = Lua::new();
|
||||||
// OR, prints go to console, return from main script goes to screen
|
let globals = lua.globals();
|
||||||
// Also need to be able to set content-type etc from within lua
|
|
||||||
|
|
||||||
// Ok(Html("Rawr").into_response())
|
use mlua::{ExternalResult, LuaSerdeExt};
|
||||||
Err(StatusCode::NOT_IMPLEMENTED)
|
|
||||||
|
let fetch_json = lua
|
||||||
|
.create_function(|lua, uri: String| {
|
||||||
|
let resp = reqwest::blocking::get(&uri)
|
||||||
|
.and_then(|resp| resp.error_for_status())
|
||||||
|
.into_lua_err()?;
|
||||||
|
let json = resp.json::<serde_json::Value>().into_lua_err()?;
|
||||||
|
lua.to_value(&json)
|
||||||
|
})
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let dbg = lua
|
||||||
|
.create_function(|_, value: LuaValue| {
|
||||||
|
dbg!(value);
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
globals.set("fetch", fetch_json).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
globals.set("dbg", dbg).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let request_table = lua.create_table().map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let headers_table = lua
|
||||||
|
.create_table_from(
|
||||||
|
request
|
||||||
|
.headers()
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, v)| (k.to_string(), v.to_str().unwrap())),
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
request_table.set("headers", headers_table).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
request_table
|
||||||
|
.set("uri", request.uri().to_string())
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
request_table
|
||||||
|
.set("method", request.method().to_string())
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Inject functions to change headers and such
|
||||||
|
globals.set("request", request_table).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let response_table = lua.create_table().map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
response_table
|
||||||
|
.set(
|
||||||
|
"headers",
|
||||||
|
lua.create_table().map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
globals.set("response", response_table).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut path = base_dir.clone();
|
||||||
|
|
||||||
|
let uri = urlencoding::decode(&request.uri().path()[1..]).map_err(|e| {
|
||||||
|
println!("{:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
path.push(&*uri);
|
||||||
|
let full_path = fs::canonicalize(&path).map_err(|e| {
|
||||||
|
println!("{:?}", e);
|
||||||
|
StatusCode::NOT_FOUND
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let full_base_path = fs::canonicalize(base_dir).map_err(|e| {
|
||||||
|
println!("{:?}", e);
|
||||||
|
StatusCode::NOT_FOUND
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if !full_path.starts_with(full_base_path) {
|
||||||
|
return Err(StatusCode::BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
let script = fs::read_to_string(full_path).map_err(|e| {
|
||||||
|
eprintln!("Lua Read Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let script = lua.load(script).eval::<LuaValue>().map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let result = lua.load("return response").eval::<Table>().map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let script = if let LuaValue::String(script) = script {
|
||||||
|
script.to_string_lossy().to_string()
|
||||||
|
} else {
|
||||||
|
serde_json::to_string(&script).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut response = Html(script).into_response();
|
||||||
|
|
||||||
|
if let Ok(headers) = result.get::<&str, Table>("headers") {
|
||||||
|
let pairs = headers.pairs::<String, String>();
|
||||||
|
|
||||||
|
for pair in pairs {
|
||||||
|
let (k, v) = pair.map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
response.headers_mut().insert(
|
||||||
|
HeaderName::from_str(&k).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?,
|
||||||
|
HeaderValue::from_str(&v).map_err(|e| {
|
||||||
|
eprintln!("Lua Error: {:?}", e);
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handler(request: Request) -> Result<Html<String>, StatusCode> {
|
async fn handler(request: Request) -> Result<Html<String>, StatusCode> {
|
||||||
|
Reference in New Issue
Block a user