Skip to content

Commit

Permalink
Improve the documentation (#799)
Browse files Browse the repository at this point in the history
* wip

* wip

* wip

* Format Rust code using rustfmt

* wip

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
chrislearn and github-actions[bot] authored Jun 4, 2024
1 parent db4396c commit a65b47b
Show file tree
Hide file tree
Showing 34 changed files with 734 additions and 125 deletions.
2 changes: 1 addition & 1 deletion crates/compression/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg_attr(docsrs, feature(doc_cfg))]

//! Compression middleware for for Savlo web server framework.
//! Compression middleware for for Savlo web framework.
//!
//! Read more: <https://salvo.rs>

Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/conn/quinn/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! `QuinnListener`` and utils.
//! `QuinnListener` and utils.
use std::io::Result as IoResult;
use std::ops::{Deref, DerefMut};
use std::future::{ready, Ready};
Expand Down
24 changes: 23 additions & 1 deletion crates/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
//! The core lib of Savlo web server framework. Read more: <https://salvo.rs>
//! The core crate of Savlo web framework.
//!
//! `salvo_core` uses a set of [feature flags] to reduce the amount of compiled and
//! optional dependencies.
//!
//! # Feature flags
//!
//! | Feature | Description | Default? |
//! | --- | --- | --- |
//! | `cookie` | Support for Cookie | ✔️ |
//! | `server` | Built-in Server implementation | ✔️ |
//! | `http1` | Support for HTTP 1.1 protocol | ✔️ |
//! | `http2` | Support for HTTP 2 protocol | ✔️ |
//! | `quinn` | Use quinn to support HTTP 3 protocol | ❌ |
//! | `test` | Utilities for testing application | ✔️ |
//! | `acme` | Automatically obtain certificates through ACME | ❌ |
//! | `rustls` | TLS built on [`rustls`](https://crates.io/crates/rustls) | ❌ |
//! | `openssl` | TLS built on [`openssl-tls`](https://crates.io/crates/openssl) | ❌ |
//! | `native-tls` | TLS built on [`native-tls`](https://crates.io/crates/native-tls) | ❌ |
//! | `unix` | Listener based on unix socket | ❌ |
//! | `tower-compat` | Adapters for `tower::Layer` and `tower::Service` | ❌ |
//! | `anyhow` | Integrate with the [`anyhow`](https://crates.io/crates/anyhow) crate | ❌ |
//! | `eyre` | Integrate with the [`eyre`](https://crates.io/crates/eyre) crate | ❌ |
#![doc(html_favicon_url = "https://salvo.rs/favicon-32x32.png")]
#![doc(html_logo_url = "https://salvo.rs/images/logo.svg")]
#![cfg_attr(docsrs, feature(doc_cfg))]
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/test/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Test utils for unit tests.
//! Utilities for testing application.

mod client;
mod request;
Expand Down
2 changes: 1 addition & 1 deletion crates/cors/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# salvo-cors

## Library to Provide a CORS protection for Salvo.
## Library adds CORS protection for Salvo web framework.

This is offical crate, so you can enable it in `Cargo.toml` like this:

Expand Down
7 changes: 3 additions & 4 deletions crates/cors/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Cross-Origin Resource Sharing (CORS) support for Savlo web server framework.
//! Library adds CORS protection for Salvo web framework.
//!
//! [CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
//!
Expand Down Expand Up @@ -166,13 +166,12 @@ impl Cors {
///
/// # Example
///
///
/// ```
/// use std::time::Duration;
/// use salvo_core::prelude::*;
/// use salvo_cors::Cors;
///
/// let cors = Cors::new().max_age(30); // 30u32 seconds
/// let cors = Cors::new().max_age(30); // 30 seconds
/// let cors = Cors::new().max_age(Duration::from_secs(30)); // or a Duration
/// ```
#[inline]
Expand Down Expand Up @@ -310,7 +309,7 @@ impl Handler for CorsHandler {
}
}

/// Returns an iterator over the three request headers that may be involved in a CORS preflight request.
/// Iterator over the three request headers that may be involved in a CORS preflight request.
///
/// This is the default set of header names returned in the `vary` header
pub fn preflight_request_headers() -> impl Iterator<Item = HeaderName> {
Expand Down
2 changes: 1 addition & 1 deletion crates/csrf/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! CSRF middleware for Savlo web server framework.
//! CSRF middleware for Savlo web framework.
//!
//! CSRF middleware for Salvo that provides CSRF (Cross-Site Request Forgery) protection.
//!
Expand Down
61 changes: 59 additions & 2 deletions crates/extra/src/affix.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,57 @@
//! affix middleware is used to add any data to depot.
//! Middleware for add any data to depot.
//!
//! Read more: <https://salvo.rs>
//! # Example
//!
//! ```no_run
//! use std::sync::Arc;
//! use std::sync::Mutex;
//!
//! use salvo_core::prelude::*;
//! use salvo_extra::affix;
//!
//! #[allow(dead_code)]
//! #[derive(Default, Clone, Debug)]
//! struct Config {
//! username: String,
//! password: String,
//! }
//!
//! #[derive(Default, Debug)]
//! struct State {
//! fails: Mutex<Vec<String>>,
//! }
//!
//! #[handler]
//! async fn hello(depot: &mut Depot) -> String {
//! let config = depot.obtain::<Config>().unwrap();
//! let custom_data = depot.get::<&str>("custom_data").unwrap();
//! let state = depot.obtain::<Arc<State>>().unwrap();
//! let mut fails_ref = state.fails.lock().unwrap();
//! fails_ref.push("fail message".into());
//! format!("Hello World\nConfig: {config:#?}\nFails: {fails_ref:#?}\nCustom Data: {custom_data}")
//! }
//!
//! #[tokio::main]
//! async fn main() {
//! let config = Config {
//! username: "root".to_string(),
//! password: "pwd".to_string(),
//! };
//! let router = Router::new()
//! .hoop(
//! affix::inject(config)
//! .inject(Arc::new(State {
//! fails: Mutex::new(Vec::new()),
//! }))
//! .insert("custom_data", "I love this world!"),
//! )
//! .get(hello)
//! .push(Router::with_path("hello").get(hello));
//!
//! let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
//! Server::new(acceptor).serve(router).await;
//! }
//! ```

use std::any::TypeId;

Expand All @@ -26,12 +77,16 @@ where
}

/// Inject a value into depot.
///
/// View [module level documentation](index.html) for more details.
#[inline]
pub fn inject<V: Send + Sync + Clone + 'static>(value: V) -> AffixList {
insert(format!("{:?}", TypeId::of::<V>()), value)
}

/// Insert a key-value pair into depot.
///
/// View [module level documentation](index.html) for more details.
#[inline]
pub fn insert<K, V>(key: K, value: V) -> AffixList
where
Expand All @@ -42,6 +97,8 @@ where
}

/// AffixList is used to add any data to depot.
///
/// View [module level documentation](index.html) for more details.
#[derive(Default)]
pub struct AffixList(Vec<Box<dyn Affix + Send + Sync + 'static>>);

Expand Down
30 changes: 28 additions & 2 deletions crates/extra/src/basic_auth.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
//! basic auth middleware.
//! Middleware for basic authentication.
//!
//! Read more: <https://salvo.rs>
//! # Example
//!
//! ```no_run
//! use salvo_core::prelude::*;
//! use salvo_extra::basic_auth::{BasicAuth, BasicAuthValidator};
//!
//! struct Validator;
//! impl BasicAuthValidator for Validator {
//! async fn validate(&self, username: &str, password: &str, _depot: &mut Depot) -> bool {
//! username == "root" && password == "pwd"
//! }
//! }
//!
//! #[handler]
//! async fn hello() -> &'static str {
//! "Hello"
//! }
//!
//! #[tokio::main]
//! async fn main() {
//! let auth_handler = BasicAuth::new(Validator);
//! let router = Router::with_hoop(auth_handler).goal(hello);
//!
//! let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
//! Server::new(acceptor).serve(router).await;
//! }
//! ```
use std::future::Future;

use base64::engine::{general_purpose, Engine};
Expand Down
74 changes: 32 additions & 42 deletions crates/extra/src/caching_headers.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,37 @@
/*!
# Salvo handlers for etag and last-modified-since headers.
This crate provides three handlers: [`ETag`], [`Modified`], and
[`CachingHeaders`].
Unless you are sure that you _don't_ want either etag or last-modified
behavior, please use the combined [`CachingHeaders`] handler.
*/
//! Middleware for etag and last-modified-since headers.
//!
//! This crate provides three handlers: [`ETag`], [`Modified`], and [`CachingHeaders`].
//! Unless you are sure that you _don't_ want either etag or last-modified
//! behavior, please use the combined [`CachingHeaders`] handler.

use etag::EntityTag;
use salvo_core::http::header::{ETAG, IF_NONE_MATCH};
use salvo_core::http::headers::{self, HeaderMapExt};
use salvo_core::http::{ResBody, StatusCode};
use salvo_core::{async_trait, Depot, FlowCtrl, Handler, Request, Response};

/**
# Etag and If-None-Match header handler
Salvo handler that provides an outbound [`etag
header`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)
after other handlers have been run, and if the request includes an
[`if-none-match`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match)
header, compares these values and sends a
[`304 not modified`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304) status,
omitting the response body.
## Streamed bodies
Note that this handler does not currently provide an etag trailer for
streamed bodies, but may do so in the future.
## Strong vs weak comparison
Etags can be compared using a strong method or a weak
method. By default, this handler allows weak comparison. To change
this setting, construct your handler with `Etag::new().strong()`.
See [`etag::EntityTag`](https://docs.rs/etag/3.0.0/etag/struct.EntityTag.html#comparison)
for further documentation.
Read more: <https://salvo.rs>
*/
/// Etag and If-None-Match header handler
///
/// Salvo handler that provides an outbound [`etag
/// header`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)
/// after other handlers have been run, and if the request includes an
/// [`if-none-match`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match)
/// header, compares these values and sends a
/// [`304 not modified`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304) status,
/// omitting the response body.
///
/// ## Streamed bodies
///
/// Note that this handler does not currently provide an etag trailer for
/// streamed bodies, but may do so in the future.
///
/// ## Strong vs weak comparison
///
/// Etags can be compared using a strong method or a weak
/// method. By default, this handler allows weak comparison. To change
/// this setting, construct your handler with `Etag::new().strong()`.
/// See [`etag::EntityTag`](https://docs.rs/etag/3.0.0/etag/struct.EntityTag.html#comparison)
/// for further documentation.
#[derive(Default, Clone, Copy, Debug)]
pub struct ETag {
strong: bool,
Expand Down Expand Up @@ -126,12 +120,10 @@ impl Handler for ETag {
}
}

/**
# A handler for the `Last-Modified` and `If-Modified-Since` header interaction.
This handler does not set a `Last-Modified` header on its own, but
relies on other handlers doing so.
*/
/// # A handler for the `Last-Modified` and `If-Modified-Since` header interaction.
///
/// This handler does not set a `Last-Modified` header on its own, but
/// relies on other handlers doing so.
#[derive(Clone, Debug, Copy, Default)]
pub struct Modified {
_private: (),
Expand Down Expand Up @@ -164,9 +156,7 @@ impl Handler for Modified {
}
}

/**
A combined handler that provides both [`ETag`] and [`Modified`] behavior.
*/
/// A combined handler that provides both [`ETag`] and [`Modified`] behavior.
#[derive(Clone, Debug, Copy, Default)]
pub struct CachingHeaders(Modified, ETag);

Expand Down
33 changes: 28 additions & 5 deletions crates/extra/src/catch_panic.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
//! Catch panic middleware.
//! Middleware for catch panic in handlers.
//!
//! Read more: <https://salvo.rs>
//! This middleware catches panics and write `500 Internal Server Error` into response.
//! This middleware should be used as the first middleware.
//!
//! # Example
//!
//! ```no_run
//! use salvo_core::prelude::*;
//! use salvo_extra::catch_panic::CatchPanic;
//!
//! #[handler]
//! async fn hello() {
//! panic!("panic error!");
//! }
//!
//! #[tokio::main]
//! async fn main() {
//! let router = Router::new().hoop(CatchPanic::new()).get(hello);
//! let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
//! Server::new(acceptor).serve(router).await;
//! }
//! ```

use std::panic::AssertUnwindSafe;

use futures_util::FutureExt;

use salvo_core::http::{Request, Response, StatusError};
use salvo_core::{async_trait, Depot, FlowCtrl, Error, Handler};

/// This middleware catches panics and write `500 INTERNAL SERVER ERROR`
/// into response. This middleware should be used as the first middleware.

/// Middleware for catch panic in handlers.
///
/// View [module level documentation](index.html) for more details.
#[derive(Default, Debug)]
pub struct CatchPanic {}
impl CatchPanic {
Expand All @@ -27,7 +50,7 @@ impl Handler for CatchPanic {
tracing::error!(error = ?e, "panic occurred");
res.render(
StatusError::internal_server_error()
.brief("panic occurred on server")
.brief("Panic occurred on server.")
.cause(Error::other(format!("{e:#?}"))),
);
}
Expand Down
Loading

0 comments on commit a65b47b

Please sign in to comment.