mirror of
https://github.com/YGGverse/nexy.git
synced 2026-03-31 09:15:28 +00:00
reorganize debug events
This commit is contained in:
parent
57dfe79568
commit
212ffeab79
10 changed files with 75 additions and 117 deletions
|
|
@ -41,12 +41,8 @@ nexy -p /path/to/public_dir
|
|||
|
||||
[default: 127.0.0.1:1900 [::1]:1900]
|
||||
|
||||
-d, --debug <DEBUG>
|
||||
Debug level
|
||||
|
||||
* `e` - error * `i` - info
|
||||
|
||||
[default: ei]
|
||||
-d, --debug
|
||||
Print debug information
|
||||
|
||||
-p, --public <PUBLIC>
|
||||
Absolute path to the public files directory
|
||||
|
|
|
|||
|
|
@ -20,12 +20,9 @@ pub struct Config {
|
|||
])]
|
||||
pub bind: Vec<String>,
|
||||
|
||||
/// Debug level
|
||||
///
|
||||
/// * `e` - error
|
||||
/// * `i` - info
|
||||
#[arg(short, long, default_value_t = String::from("ei"))]
|
||||
pub debug: String,
|
||||
/// Print debug information
|
||||
#[arg(short, long, default_value_t = false)]
|
||||
pub debug: bool,
|
||||
|
||||
/// Absolute path to the public files directory
|
||||
#[arg(short, long)]
|
||||
|
|
|
|||
12
src/main.rs
12
src/main.rs
|
|
@ -5,10 +5,10 @@ mod session;
|
|||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
use clap::Parser;
|
||||
let a = config::Config::parse();
|
||||
let s = std::sync::Arc::new(session::Session::init(&a)?);
|
||||
for b in a.bind {
|
||||
s.debug.info(&format!("start server on `{b}`..."));
|
||||
let c = config::Config::parse();
|
||||
let s = std::sync::Arc::new(session::Session::init(&c)?);
|
||||
for b in c.bind {
|
||||
println!("start server on `{b}`...");
|
||||
match std::net::TcpListener::bind(&b) {
|
||||
Ok(r) => {
|
||||
std::thread::spawn({
|
||||
|
|
@ -16,9 +16,7 @@ fn main() -> anyhow::Result<()> {
|
|||
move || server::start(r, &s)
|
||||
});
|
||||
}
|
||||
Err(e) => s
|
||||
.debug
|
||||
.error(&format!("failed to start server on `{b}`: `{e}`")),
|
||||
Err(e) => eprintln!("failed to start server on `{b}`: `{e}`"),
|
||||
}
|
||||
}
|
||||
std::thread::park();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/// Internal types
|
||||
/// Internal server response types
|
||||
pub enum Response<'a> {
|
||||
/// Includes reference to the original request
|
||||
AccessDenied(&'a str),
|
||||
/// Includes server-side error description
|
||||
InternalServerError(String),
|
||||
/// Includes query + server-side error description
|
||||
InternalServerError(&'a str, String),
|
||||
/// Includes reference to the original request
|
||||
NotFound(&'a str),
|
||||
/// Includes bytes array
|
||||
|
|
|
|||
|
|
@ -12,15 +12,11 @@ pub fn start(server: TcpListener, session: &Arc<Session>) {
|
|||
let session = session.clone();
|
||||
move || match Connection::init(&session, stream) {
|
||||
Ok(connection) => connection.handle(),
|
||||
Err(e) => session
|
||||
.debug
|
||||
.error(&format!("failed to init connection: `{e}`")),
|
||||
Err(e) => eprintln!("failed to init connection: `{e}`"),
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(e) => session
|
||||
.debug
|
||||
.error(&format!("failed to accept incoming connection: `{e}`")),
|
||||
Err(e) => eprintln!("failed to accept incoming connection: `{e}`"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,10 +35,12 @@ impl Connection {
|
|||
let mut t = 0; // total bytes
|
||||
match self.request() {
|
||||
Ok(q) => {
|
||||
self.session.debug.info(&format!(
|
||||
if self.session.is_debug {
|
||||
println!(
|
||||
"[{}] < [{}] request `{q}`...",
|
||||
self.address.server, self.address.client
|
||||
));
|
||||
)
|
||||
}
|
||||
if let Some(ref i) = self.session.request {
|
||||
i.add(&self.address.client, &q)
|
||||
}
|
||||
|
|
@ -51,10 +53,13 @@ impl Connection {
|
|||
.clf(&self.address.client, Some(&q), 0, t);
|
||||
}
|
||||
Err(e) => {
|
||||
t += self.response(Response::InternalServerError(format!(
|
||||
t += self.response(Response::InternalServerError(
|
||||
"",
|
||||
format!(
|
||||
"[{}] < [{}] failed to handle incoming request: `{e}`",
|
||||
self.address.server, self.address.client
|
||||
)));
|
||||
),
|
||||
));
|
||||
self.session
|
||||
.access_log
|
||||
.clf(&self.address.client, None, 1, t);
|
||||
|
|
@ -87,50 +92,61 @@ impl Connection {
|
|||
)
|
||||
}
|
||||
}
|
||||
Response::InternalServerError(e) => {
|
||||
self.session.debug.error(&e);
|
||||
Response::InternalServerError(q, e) => {
|
||||
eprintln!(
|
||||
"[{}] > [{}] `{q}`: internal server error: `{e}`",
|
||||
self.address.server, self.address.client
|
||||
);
|
||||
self.session.template.internal_server_error()
|
||||
}
|
||||
Response::AccessDenied(q) => {
|
||||
self.session.debug.error(&format!(
|
||||
eprintln!(
|
||||
"[{}] < [{}] access to `{q}` denied.",
|
||||
self.address.server, self.address.client
|
||||
));
|
||||
);
|
||||
self.session.template.access_denied()
|
||||
}
|
||||
Response::NotFound(q) => {
|
||||
self.session.debug.error(&format!(
|
||||
eprintln!(
|
||||
"[{}] < [{}] requested resource `{q}` not found.",
|
||||
self.address.server, self.address.client
|
||||
));
|
||||
);
|
||||
self.session.template.not_found()
|
||||
}
|
||||
};
|
||||
match self.stream.write_all(bytes) {
|
||||
Ok(()) => self.session.debug.info(&format!(
|
||||
Ok(()) => {
|
||||
if self.session.is_debug {
|
||||
println!(
|
||||
"[{}] > [{}] sent {} bytes response.",
|
||||
self.address.server,
|
||||
self.address.client,
|
||||
bytes.len()
|
||||
)),
|
||||
Err(e) => self.session.debug.error(&format!(
|
||||
)
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!(
|
||||
"[{}] ! [{}] failed to response: `{e}`",
|
||||
self.address.server, self.address.client,
|
||||
)),
|
||||
),
|
||||
};
|
||||
bytes.len()
|
||||
}
|
||||
|
||||
fn shutdown(self) {
|
||||
match self.stream.shutdown(std::net::Shutdown::Both) {
|
||||
Ok(()) => self.session.debug.info(&format!(
|
||||
Ok(()) => {
|
||||
if self.session.is_debug {
|
||||
println!(
|
||||
"[{}] - [{}] connection closed by server.",
|
||||
self.address.server, self.address.client,
|
||||
)),
|
||||
Err(e) => self.session.debug.error(&format!(
|
||||
)
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!(
|
||||
"[{}] > [{}] failed to close connection: `{e}`",
|
||||
self.address.server, self.address.client,
|
||||
)),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
mod access_log;
|
||||
mod debug;
|
||||
mod public;
|
||||
mod request;
|
||||
mod template;
|
||||
|
||||
use {access_log::AccessLog, debug::Debug, public::Public, request::Request, template::Template};
|
||||
use {access_log::AccessLog, public::Public, request::Request, template::Template};
|
||||
|
||||
/// Shared, multi-thread features for the current server session
|
||||
pub struct Session {
|
||||
pub access_log: AccessLog,
|
||||
pub debug: Debug,
|
||||
pub public: Public,
|
||||
pub request: Option<Request>,
|
||||
pub template: Template,
|
||||
pub is_debug: bool,
|
||||
}
|
||||
|
||||
impl Session {
|
||||
|
|
@ -20,7 +19,6 @@ impl Session {
|
|||
let template = Template::init(config)?;
|
||||
Ok(Self {
|
||||
access_log: AccessLog::init(config)?,
|
||||
debug: Debug::init(config)?,
|
||||
public: Public::init(config)?,
|
||||
request: if template.welcome.contains("{hosts}")
|
||||
|| template.welcome.contains("{hits}")
|
||||
|
|
@ -32,6 +30,7 @@ impl Session {
|
|||
None // do not int request collector if its features not in use
|
||||
},
|
||||
template,
|
||||
is_debug: config.debug,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
mod level;
|
||||
use level::Level;
|
||||
|
||||
pub struct Debug(Vec<Level>);
|
||||
|
||||
impl Debug {
|
||||
pub fn init(config: &crate::config::Config) -> anyhow::Result<Self> {
|
||||
let mut l = Vec::with_capacity(config.debug.len());
|
||||
for s in config.debug.to_lowercase().chars() {
|
||||
l.push(Level::parse(s)?);
|
||||
}
|
||||
Ok(Self(l))
|
||||
}
|
||||
|
||||
pub fn error(&self, message: &str) {
|
||||
if self.0.contains(&Level::Error) {
|
||||
eprintln!("[{}] [error] {message}", now());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn info(&self, message: &str) {
|
||||
if self.0.contains(&Level::Info) {
|
||||
println!("[{}] [info] {message}", now());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn now() -> String {
|
||||
chrono::Local::now().to_rfc3339()
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
use anyhow::{Result, bail};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum Level {
|
||||
Error,
|
||||
Info,
|
||||
}
|
||||
|
||||
impl Level {
|
||||
pub fn parse(value: char) -> Result<Self> {
|
||||
match value {
|
||||
'e' => Ok(Self::Error),
|
||||
'i' => Ok(Self::Info),
|
||||
_ => bail!("unsupported debug level `{value}`!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ impl Public {
|
|||
Ok(t) => match (t.is_dir(), t.is_file()) {
|
||||
(true, _) => callback(match self.list(&p) {
|
||||
Ok(list) => Response::Directory(query, list, p == self.public_dir),
|
||||
Err(e) => Response::InternalServerError(e.to_string()),
|
||||
Err(e) => Response::InternalServerError(query, e.to_string()),
|
||||
}),
|
||||
(_, true) => match fs::File::open(p) {
|
||||
Ok(mut f) => loop {
|
||||
|
|
@ -70,21 +70,24 @@ impl Public {
|
|||
Ok(0) => break,
|
||||
Ok(n) => callback(Response::File(&b[..n])),
|
||||
Err(e) => {
|
||||
return callback(Response::InternalServerError(format!(
|
||||
"failed to read response chunk for `{query}`: `{e}`"
|
||||
)));
|
||||
return callback(Response::InternalServerError(
|
||||
query,
|
||||
format!("failed to read response chunk: `{e}`"),
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => callback(Response::InternalServerError(format!(
|
||||
"failed to read response for query`{query}`: `{e}`"
|
||||
))),
|
||||
Err(e) => callback(Response::InternalServerError(
|
||||
query,
|
||||
format!("failed to read response: `{e}`"),
|
||||
)),
|
||||
},
|
||||
_ => panic!(), // unexpected
|
||||
},
|
||||
Err(e) => callback(Response::InternalServerError(format!(
|
||||
"failed to read storage for `{query}`: `{e}`"
|
||||
))),
|
||||
Err(e) => callback(Response::InternalServerError(
|
||||
query,
|
||||
format!("failed to read storage: `{e}`"),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue