Compare commits

...

4 Commits
devel ... docs

9 changed files with 35 additions and 0 deletions

View File

@ -58,3 +58,6 @@ required-features = ["serve_dir"]
[[example]] [[example]]
name = "ratelimiting" name = "ratelimiting"
required-features = ["ratelimiting"] required-features = ["ratelimiting"]
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]

View File

@ -26,6 +26,7 @@ use rustls::*;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[cfg(feature = "certgen")] #[cfg(feature = "certgen")]
#[cfg_attr(docsrs, doc(cfg(feature = "certgen")))]
/// The mode to use for determining the domains to use for a new certificate. /// The mode to use for determining the domains to use for a new certificate.
/// ///
/// Used to configure a [`Server`] using [`set_certificate_generation_mode()`] /// Used to configure a [`Server`] using [`set_certificate_generation_mode()`]
@ -45,6 +46,7 @@ pub enum CertGenMode {
} }
#[cfg(feature = "certgen")] #[cfg(feature = "certgen")]
#[cfg_attr(docsrs, doc(cfg(feature = "certgen")))]
impl CertGenMode { impl CertGenMode {
/// Generate a new self-signed certificate /// Generate a new self-signed certificate
/// ///

View File

@ -56,6 +56,7 @@ pub enum Handler {
StaticHandler(Response), StaticHandler(Response),
#[cfg(feature = "serve_dir")] #[cfg(feature = "serve_dir")]
#[cfg_attr(docsrs, doc(cfg(feature = "serve_dir")))]
/// A handler that serves a directory, including a directory listing /// A handler that serves a directory, including a directory listing
/// ///
/// Most often created with [`From<PathBuf>`] /// Most often created with [`From<PathBuf>`]
@ -208,6 +209,7 @@ impl From<&Document> for Handler {
} }
#[cfg(feature = "serve_dir")] #[cfg(feature = "serve_dir")]
#[doc(cfg(feature = "serve_dir"))]
impl From<PathBuf> for Handler { impl From<PathBuf> for Handler {
/// Serve files from a directory /// Serve files from a directory
/// ///

View File

@ -1,4 +1,5 @@
#![warn(missing_docs)] #![warn(missing_docs)]
#![feature(doc_cfg)]
#![doc(html_logo_url = "https://raw.githubusercontent.com/twitter/twemoji/master/assets/svg/1f30c.svg")] #![doc(html_logo_url = "https://raw.githubusercontent.com/twitter/twemoji/master/assets/svg/1f30c.svg")]
//! Kochab is an ergonomic and intuitive library for quickly building highly functional //! Kochab is an ergonomic and intuitive library for quickly building highly functional
//! and advanced Gemini applications on either SCGI or raw Gemini. //! and advanced Gemini applications on either SCGI or raw Gemini.
@ -240,6 +241,7 @@ pub mod routing;
#[cfg(feature = "ratelimiting")] #[cfg(feature = "ratelimiting")]
mod ratelimiting; mod ratelimiting;
#[cfg(feature = "user_management")] #[cfg(feature = "user_management")]
#[doc(cfg(feature = "user_management"))]
pub mod user_management; pub mod user_management;
#[cfg(feature = "gemini_srv")] #[cfg(feature = "gemini_srv")]
mod cert; mod cert;
@ -247,6 +249,7 @@ mod cert;
#[cfg(feature="user_management")] #[cfg(feature="user_management")]
use user_management::UserManager; use user_management::UserManager;
#[cfg(feature = "certgen")] #[cfg(feature = "certgen")]
#[doc(cfg(feature = "certgen"))]
pub use cert::CertGenMode; pub use cert::CertGenMode;
pub use uriparse::URIReference; pub use uriparse::URIReference;
@ -716,6 +719,7 @@ impl Server {
} }
#[cfg(feature="user_management")] #[cfg(feature="user_management")]
#[doc(cfg(feature = "user_management"))]
/// Sets the directory to store user data in /// Sets the directory to store user data in
/// ///
/// This will only be used if a database is not provided with [`set_database()`]. /// This will only be used if a database is not provided with [`set_database()`].
@ -729,6 +733,7 @@ impl Server {
} }
#[cfg(feature="user_management")] #[cfg(feature="user_management")]
#[doc(cfg(feature = "user_management"))]
/// Sets a specific database to use /// Sets a specific database to use
/// ///
/// This opens to trees within the database, both namespaced to avoid collisions. /// This opens to trees within the database, both namespaced to avoid collisions.
@ -743,6 +748,7 @@ impl Server {
} }
#[cfg(feature="certgen")] #[cfg(feature="certgen")]
#[doc(cfg(feature = "certgen"))]
/// Determine where certificate config comes from, if generation is required /// Determine where certificate config comes from, if generation is required
/// ///
/// If a certificate & keyfile are not available on the provided path, they can be /// If a certificate & keyfile are not available on the provided path, they can be
@ -755,6 +761,7 @@ impl Server {
} }
#[cfg(feature = "gemini_srv")] #[cfg(feature = "gemini_srv")]
#[doc(cfg(feature = "gemini_srv"))]
/// Sets the directory that kochab should look for TLS certs and keys into /// Sets the directory that kochab should look for TLS certs and keys into
/// ///
/// Northstar will look for files called `cert.pem` and `key.pem` in the provided /// Northstar will look for files called `cert.pem` and `key.pem` in the provided
@ -771,6 +778,7 @@ impl Server {
} }
#[cfg(feature = "gemini_srv")] #[cfg(feature = "gemini_srv")]
#[doc(cfg(feature = "gemini_srv"))]
/// Set the path to the TLS certificate kochab will use /// Set the path to the TLS certificate kochab will use
/// ///
/// This defaults to `cert/cert.pem`. /// This defaults to `cert/cert.pem`.
@ -783,6 +791,7 @@ impl Server {
} }
#[cfg(feature = "gemini_srv")] #[cfg(feature = "gemini_srv")]
#[doc(cfg(feature = "gemini_srv"))]
/// Set the path to the ertificate key kochab will use /// Set the path to the ertificate key kochab will use
/// ///
/// This defaults to `cert/key.pem`. /// This defaults to `cert/key.pem`.
@ -868,6 +877,7 @@ impl Server {
} }
#[cfg(feature="ratelimiting")] #[cfg(feature="ratelimiting")]
#[doc(cfg(feature = "ratelimiting"))]
/// Add a rate limit to a route /// Add a rate limit to a route
/// ///
/// The server will allow at most `burst` connections to any endpoints under this /// The server will allow at most `burst` connections to any endpoints under this
@ -1000,6 +1010,7 @@ impl Server {
} }
#[cfg(feature = "scgi_srv")] #[cfg(feature = "scgi_srv")]
#[doc(cfg(feature = "scgi_srv"))]
/// Start serving requests on a given unix socket /// Start serving requests on a given unix socket
/// ///
/// Requires an address in the form of a path to bind to. This is only available when /// Requires an address in the form of a path to bind to. This is only available when

View File

@ -27,6 +27,7 @@ pub enum Body {
impl Body { impl Body {
/// Called by [`Response::rewrite_all`] /// Called by [`Response::rewrite_all`]
#[cfg(feature="scgi_srv")] #[cfg(feature="scgi_srv")]
#[cfg_attr(docsrs, doc(cfg(feature = "scgi_srv")))]
pub (crate) async fn rewrite_all(&mut self, based_on: &crate::Request) -> std::io::Result<bool> { pub (crate) async fn rewrite_all(&mut self, based_on: &crate::Request) -> std::io::Result<bool> {
let bytes = match self { let bytes = match self {
Self::Bytes(bytes) => { Self::Bytes(bytes) => {
@ -101,6 +102,7 @@ impl<'a> From<&'a str> for Body {
} }
#[cfg(feature="serve_dir")] #[cfg(feature="serve_dir")]
#[cfg_attr(docsrs, doc(cfg(feature = "serve_dir")))]
impl From<File> for Body { impl From<File> for Body {
fn from(file: File) -> Self { fn from(file: File) -> Self {
Self::Reader(Box::new(file)) Self::Reader(Box::new(file))

View File

@ -212,6 +212,7 @@ impl Request {
} }
#[cfg(feature="scgi_srv")] #[cfg(feature="scgi_srv")]
#[doc(cfg(feature = "scgi_srv"))]
/// View any headers sent by the SCGI client /// View any headers sent by the SCGI client
/// ///
/// When an SCGI client delivers a request (e.g. when your gemini server sends a /// When an SCGI client delivers a request (e.g. when your gemini server sends a
@ -288,6 +289,7 @@ impl Request {
} }
#[cfg(feature="user_management")] #[cfg(feature="user_management")]
#[doc(cfg(feature = "user_management"))]
/// Attempt to determine the user who sent this request /// Attempt to determine the user who sent this request
/// ///
/// May return a variant depending on if the client used a client certificate, and if /// May return a variant depending on if the client used a client certificate, and if
@ -300,6 +302,7 @@ impl Request {
} }
#[cfg(feature="user_management")] #[cfg(feature="user_management")]
#[doc(cfg(feature = "user_management"))]
/// Expose the server's UserManager /// Expose the server's UserManager
/// ///
/// Can be used to query users, or directly access the database /// Can be used to query users, or directly access the database

View File

@ -23,6 +23,7 @@ mod manager;
#[cfg(feature = "user_management_routes")] #[cfg(feature = "user_management_routes")]
mod routes; mod routes;
#[cfg(feature = "user_management_routes")] #[cfg(feature = "user_management_routes")]
#[doc(cfg(feature = "user_management_routes"))]
pub use routes::UserManagementRoutes; pub use routes::UserManagementRoutes;
pub use manager::UserManager; pub use manager::UserManager;
pub use user::User; pub use user::User;
@ -68,6 +69,7 @@ pub enum UserManagerError {
DeserializeError(DeserializeError), DeserializeError(DeserializeError),
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
/// There was an error hashing or checking the user's password. /// There was an error hashing or checking the user's password.
/// ///
/// This likely indicates database corruption, and should be handled in the same way /// This likely indicates database corruption, and should be handled in the same way
@ -112,6 +114,7 @@ impl From<DeserializeError> for UserManagerError {
} }
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
impl From<argon2::Error> for UserManagerError { impl From<argon2::Error> for UserManagerError {
fn from(error: argon2::Error) -> Self { fn from(error: argon2::Error) -> Self {
Self::Argon2Error(error) Self::Argon2Error(error)
@ -125,6 +128,7 @@ impl std::error::Error for UserManagerError {
Self::DatabaseTransactionError(e) => Some(e), Self::DatabaseTransactionError(e) => Some(e),
Self::DeserializeError(e) => Some(e), Self::DeserializeError(e) => Some(e),
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
Self::Argon2Error(e) => Some(e), Self::Argon2Error(e) => Some(e),
_ => None _ => None
} }
@ -145,6 +149,7 @@ impl std::fmt::Display for UserManagerError {
Self::DeserializeError(e) => Self::DeserializeError(e) =>
write!(f, "Recieved messy data from database, possible corruption: {}", e), write!(f, "Recieved messy data from database, possible corruption: {}", e),
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
Self::Argon2Error(e) => Self::Argon2Error(e) =>
write!(f, "Argon2 Error, likely malformed password hash, possible database corruption: {}", e), write!(f, "Argon2 Error, likely malformed password hash, possible database corruption: {}", e),
} }

View File

@ -164,6 +164,7 @@ impl NotSignedInUser {
} }
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
/// Attach this certificate to an existing user /// Attach this certificate to an existing user
/// ///
/// Try to add this certificate to another user using a username and password. If /// Try to add this certificate to another user using a username and password. If
@ -284,6 +285,7 @@ impl<UserData: Serialize + DeserializeOwned> RegisteredUser<UserData> {
} }
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
/// Check a password against the user's password hash /// Check a password against the user's password hash
/// ///
/// # Errors /// # Errors
@ -311,6 +313,7 @@ impl<UserData: Serialize + DeserializeOwned> RegisteredUser<UserData> {
} }
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
/// Set's the password for this user /// Set's the password for this user
/// ///
/// By default, users have no password, meaning the cannot add any certificates beyond /// By default, users have no password, meaning the cannot add any certificates beyond
@ -451,6 +454,7 @@ impl<UserData: Serialize + DeserializeOwned> RegisteredUser<UserData> {
} }
#[cfg(feature = "user_management_advanced")] #[cfg(feature = "user_management_advanced")]
#[doc(cfg(feature = "user_management_advanced"))]
/// Check if the user has a password set /// Check if the user has a password set
/// ///
/// Since authentication is done using client certificates, users aren't required to /// Since authentication is done using client certificates, users aren't required to

View File

@ -16,6 +16,7 @@ use crate::types::{Document, document::HeadingLevel::*};
use crate::types::Response; use crate::types::Response;
#[cfg(feature="serve_dir")] #[cfg(feature="serve_dir")]
#[doc(cfg(feature = "serve_dir"))]
pub async fn serve_file<P: AsRef<Path>>(path: P, mime: &str) -> Response { pub async fn serve_file<P: AsRef<Path>>(path: P, mime: &str) -> Response {
let path = path.as_ref(); let path = path.as_ref();
@ -34,6 +35,7 @@ pub async fn serve_file<P: AsRef<Path>>(path: P, mime: &str) -> Response {
} }
#[cfg(feature="serve_dir")] #[cfg(feature="serve_dir")]
#[doc(cfg(feature = "serve_dir"))]
pub async fn serve_dir<D: AsRef<Path>, P: AsRef<Path>>(dir: D, virtual_path: &[P]) -> Response { pub async fn serve_dir<D: AsRef<Path>, P: AsRef<Path>>(dir: D, virtual_path: &[P]) -> Response {
debug!("Dir: {}", dir.as_ref().display()); debug!("Dir: {}", dir.as_ref().display());
let dir = dir.as_ref(); let dir = dir.as_ref();
@ -129,6 +131,7 @@ async fn serve_dir_listing<P: AsRef<Path>, B: AsRef<Path>>(path: P, virtual_path
} }
#[cfg(feature="serve_dir")] #[cfg(feature="serve_dir")]
#[doc(cfg(feature = "serve_dir"))]
pub fn guess_mime_from_path<P: AsRef<Path>>(path: P) -> &'static str { pub fn guess_mime_from_path<P: AsRef<Path>>(path: P) -> &'static str {
let path = path.as_ref(); let path = path.as_ref();
let extension = path.extension().and_then(|s| s.to_str()); let extension = path.extension().and_then(|s| s.to_str());