.
This commit is contained in:
parent
e3f54d988e
commit
a5ed3001e2
12 changed files with 1763 additions and 14 deletions
1523
Cargo.lock
generated
1523
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -6,4 +6,8 @@ version = "0.1.0"
|
|||
license = "MIT License"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
[dependencies]
|
||||
actix-web = "4"
|
||||
log = "0.4"
|
||||
fern = "0.7"
|
||||
gitea_sdk = "0.5"
|
38
output.log
Normal file
38
output.log
Normal file
|
@ -0,0 +1,38 @@
|
|||
[INFO actix_server::builder] starting 16 workers
|
||||
[INFO actix_server::server] Actix runtime found; starting in Actix runtime
|
||||
[INFO actix_server::server] starting service: "actix-web-service-127.0.0.1:8080", workers: 16, listening on: 127.0.0.1:8080
|
||||
[DEBUG pages::storage::backend_filesystem] Checking if site a exists: true
|
||||
[DEBUG pages::storage::backend_filesystem] Asset a is a file
|
||||
[DEBUG pages::storage::backend_filesystem] Checking if site a exists: true
|
||||
[DEBUG pages::storage::backend_filesystem] Asset a is a file
|
||||
[INFO actix_server::server] SIGINT received; starting forced shutdown
|
||||
[DEBUG actix_server::accept] paused accepting connections on 127.0.0.1:8080
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::worker] shutting down idle worker
|
||||
[INFO actix_server::accept] accept thread stopped
|
||||
[INFO actix_server::builder] starting 16 workers
|
||||
[INFO actix_server::server] Actix runtime found; starting in Actix runtime
|
||||
[INFO actix_server::server] starting service: "actix-web-service-127.0.0.1:8080", workers: 16, listening on: 127.0.0.1:8080
|
||||
[DEBUG pages::storage::backend_filesystem] Checking if site a exists: true
|
||||
[DEBUG pages::storage::backend_filesystem] Asset /index.html is a file
|
||||
[DEBUG pages::storage::backend_filesystem] Checking if site a exists: true
|
||||
[DEBUG pages::storage::backend_filesystem] Asset exampleDir is a directory
|
||||
[DEBUG pages::storage::backend_filesystem] Requested asset is a directory: Inferring index.html
|
||||
[DEBUG pages::storage::backend_filesystem] Checking if site a exists: true
|
||||
[DEBUG pages::storage::backend_filesystem] Asset exampleDir/test.html is a file
|
||||
[DEBUG pages::storage::backend_filesystem] Checking if site a exists: true
|
||||
[DEBUG pages::storage::backend_filesystem] Asset exampleDir/index.html is a file
|
1
src/lib.rs
Normal file
1
src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod storage;
|
67
src/main.rs
67
src/main.rs
|
@ -1,5 +1,66 @@
|
|||
pub mod storage;
|
||||
use actix_web::{get, App, HttpRequest, HttpServer, Result};
|
||||
use pages::storage::{backend_filesystem::PageStorageBackendFilesystem, PageStorageRead};
|
||||
|
||||
fn main() {
|
||||
|
||||
#[get("/page/{site_id}/{url:.*}")]
|
||||
async fn asset(req: HttpRequest) -> Result<String> {
|
||||
let v1: String = req.match_info().get("site_id").unwrap().parse().unwrap();
|
||||
let v2: String = req.match_info().query("url").parse().unwrap();
|
||||
|
||||
let storage = PageStorageBackendFilesystem::new(
|
||||
"C:/Users/anmei/Documents/MSS-LLC/pages/test_dir".to_string()
|
||||
).unwrap();
|
||||
|
||||
match storage.asset_contents(&v1, &v2) {
|
||||
Ok(content) => Ok(String::from_utf8(content).unwrap()),
|
||||
Err(_) => Ok("Error".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/page/{site_id}")]
|
||||
async fn index(req: HttpRequest) -> Result<String> {
|
||||
let v1: String = req.match_info().get("site_id").unwrap().parse().unwrap();
|
||||
let v2: String = req.match_info().query("url").parse().unwrap();
|
||||
|
||||
let storage = PageStorageBackendFilesystem::new(
|
||||
"C:/Users/anmei/Documents/MSS-LLC/pages/test_dir".to_string()
|
||||
).unwrap();
|
||||
|
||||
let fmt = format!("{}/index.html", &v2);
|
||||
|
||||
match storage.asset_contents(&v1, &fmt) {
|
||||
Ok(content) => Ok(String::from_utf8(content).unwrap()),
|
||||
Err(_) => Ok("Error".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_logger() -> Result<(), fern::InitError> {
|
||||
fern::Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"[{} {}] {}",
|
||||
record.level(),
|
||||
record.target(),
|
||||
message
|
||||
))
|
||||
})
|
||||
.level(log::LevelFilter::Debug)
|
||||
.chain(std::io::stdout())
|
||||
.chain(fern::log_file("output.log")?)
|
||||
.apply()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let _ = setup_logger();
|
||||
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.service(index)
|
||||
.service(asset)
|
||||
})
|
||||
.bind(("127.0.0.1", 8080))?
|
||||
.run()
|
||||
.await
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
|
||||
pub trait PageStorageRead {
|
||||
fn url_contents(site_id: &str, url: &str) -> Result<[u8], ()>;
|
||||
fn url_exists(site_id: &str, url: &str) -> Result<bool, ()>;
|
||||
}
|
||||
|
||||
pub trait PageStorageWrite {
|
||||
|
||||
}
|
100
src/storage/backend_filesystem.rs
Normal file
100
src/storage/backend_filesystem.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
use std::{fs, io::Read, path::{self, Path}};
|
||||
|
||||
use log::debug;
|
||||
|
||||
use super::{PageStorageAssetType, PageStorageError, PageStorageRead};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PageStorageBackendFilesystemError {
|
||||
InvalidDirectory(String)
|
||||
}
|
||||
|
||||
pub struct PageStorageBackendFilesystem {
|
||||
storage_directory: String
|
||||
}
|
||||
|
||||
impl PageStorageBackendFilesystem {
|
||||
pub fn new(storage_directory: String) -> Result<Self, PageStorageBackendFilesystemError> {
|
||||
// TODO: Perform checks on storage directory.
|
||||
// - Is it a valid directory?
|
||||
// - Is it a system directory?
|
||||
Ok(Self {
|
||||
storage_directory
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Stores page assets on filesystem as the following layout:
|
||||
// - page_data
|
||||
// - [...site_id...]
|
||||
// - [...site assets...]
|
||||
// ! WARNING: THIS IS NOT CURRENTLY ROBUST ENOUGH FOR PRODUCTION
|
||||
impl PageStorageRead for PageStorageBackendFilesystem {
|
||||
fn asset_contents(&self, site_id: &str, url: &str) -> Result<Vec<u8>, super::PageStorageError> {
|
||||
match self.asset_exists(site_id, url) {
|
||||
Ok(exists) => {
|
||||
let mut url: String = url.to_string();
|
||||
match exists {
|
||||
PageStorageAssetType::IsFile => {},
|
||||
PageStorageAssetType::IsDirectory => {
|
||||
debug!("Requested asset is a directory: Inferring index.html");
|
||||
url = format!("{}/index.html", url);
|
||||
}
|
||||
PageStorageAssetType::IsNone => return Err(PageStorageError::AssetDoesNotExist(url.to_string()))
|
||||
}
|
||||
// TODO: Reprocessing the path - Make it only do it once
|
||||
let path_raw = format!("{}/{}/{}", &self.storage_directory, site_id, url);
|
||||
let path: &Path = Path::new(&path_raw);
|
||||
|
||||
let file_result = fs::File::open(path);
|
||||
match file_result {
|
||||
Ok(mut file) => {
|
||||
let mut vec = Vec::new();
|
||||
// TODO: Unused result
|
||||
file.read_to_end(&mut vec);
|
||||
return Ok(vec)
|
||||
}
|
||||
Err(_) => Err(super::PageStorageError::InternalError("".to_string()))
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn asset_exists(&self, site_id: &str, url: &str) -> Result<PageStorageAssetType, super::PageStorageError> {
|
||||
match self.site_exists(site_id) {
|
||||
Ok(exists) => {
|
||||
match exists {
|
||||
true => {}
|
||||
false => return Err(PageStorageError::SiteDoesNotExist(site_id.to_string()))
|
||||
}
|
||||
// TODO: VALIDATE URL
|
||||
// TODO: We're reprocessing the path here - Make it only do it once
|
||||
let path_raw = format!("{}/{}/{}", &self.storage_directory, site_id, url);
|
||||
let path: &Path = Path::new(&path_raw);
|
||||
if !path.exists() {
|
||||
debug!("Asset {} does not exist", url);
|
||||
return Ok(PageStorageAssetType::IsNone)
|
||||
} if path.is_file() {
|
||||
debug!("Asset {} is a file", url);
|
||||
return Ok(PageStorageAssetType::IsFile)
|
||||
} else if path.is_dir() {
|
||||
debug!("Asset {} is a directory", url);
|
||||
return Ok(PageStorageAssetType::IsDirectory)
|
||||
} else {
|
||||
return Err(PageStorageError::InternalError("Page exists, but is neither a file nor directory".to_string()))
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn site_exists(&self, site_id: &str) -> Result<bool, super::PageStorageError> {
|
||||
// TODO: VALIDATE SITE_ID
|
||||
let path_raw = format!("{}/{}", &self.storage_directory, site_id);
|
||||
let path: &Path = Path::new(&path_raw);
|
||||
let exists = path.exists() && path.is_dir();
|
||||
debug!("Checking if site {} exists: {}", site_id, exists);
|
||||
Ok(exists)
|
||||
}
|
||||
}
|
3
src/storage/gitea_filesystem.rs
Normal file
3
src/storage/gitea_filesystem.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub struct PageBackendFilesystemGitea {
|
||||
client:
|
||||
}
|
20
src/storage/mod.rs
Normal file
20
src/storage/mod.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
pub mod backend_filesystem;
|
||||
pub mod gitea_filesystem;
|
||||
|
||||
pub enum PageStorageError {
|
||||
SiteDoesNotExist(String),
|
||||
AssetDoesNotExist(String),
|
||||
InternalError(String)
|
||||
}
|
||||
|
||||
pub enum PageStorageAssetType {
|
||||
IsNone,
|
||||
IsFile,
|
||||
IsDirectory
|
||||
}
|
||||
|
||||
pub trait PageStorageRead {
|
||||
fn asset_contents(&self, site_id: &str, url: &str) -> Result<Vec<u8>, PageStorageError>;
|
||||
fn asset_exists(&self, site_id: &str, url: &str) -> Result<PageStorageAssetType, PageStorageError>;
|
||||
fn site_exists(&self, site_id: &str) -> Result<bool, PageStorageError>;
|
||||
}
|
3
test_dir/a/exampleDir/index.html
Normal file
3
test_dir/a/exampleDir/index.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<html>
|
||||
<h1>Example Directory Index</h1>
|
||||
</html>
|
3
test_dir/a/exampleDir/test.html
Normal file
3
test_dir/a/exampleDir/test.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<html>
|
||||
<p>Specific HTML file test</p>
|
||||
</html>
|
3
test_dir/a/index.html
Normal file
3
test_dir/a/index.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<html>
|
||||
<h1>Test</h1>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue