docs: add doc-comments to lib.rs and client
This commit is contained in:
parent
307e54f256
commit
39b1009048
3 changed files with 57 additions and 3 deletions
|
@ -20,12 +20,15 @@ pub struct ClientBuilder {
|
|||
}
|
||||
|
||||
impl Default for ClientBuilder {
|
||||
/// Same as [`ClientBuilder::new()`].
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientBuilder {
|
||||
/// Instantiate a builder with empty [`rustls::RootCertStore`],
|
||||
/// no cert verifiers and default TLS versions.
|
||||
pub fn new() -> Self {
|
||||
ClientBuilder {
|
||||
root_certs: rustls::RootCertStore::empty(),
|
||||
|
@ -35,6 +38,7 @@ impl ClientBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/// Construct a [`Client`] from the configuration.
|
||||
pub fn build(self) -> Client {
|
||||
let provider = rustls::crypto::CryptoProvider::get_default()
|
||||
.cloned()
|
||||
|
@ -82,12 +86,17 @@ impl ClientBuilder {
|
|||
Client::from(tls_config)
|
||||
}
|
||||
|
||||
/// Include webpki trust anchors.
|
||||
/// Not recommended (useless) as most Gemini capsules use self-signed
|
||||
/// TLS certs and properly configured TOFU policy is enough.
|
||||
pub fn with_webpki_roots(mut self) -> Self {
|
||||
self.root_certs
|
||||
.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
||||
self
|
||||
}
|
||||
|
||||
/// Include custom trust anchors.
|
||||
/// Not recommended (useless), see note for [`ClientBuilder::with_webpki_roots`].
|
||||
pub fn with_custom_roots(
|
||||
mut self,
|
||||
iter: impl IntoIterator<Item = TrustAnchor<'static>>,
|
||||
|
@ -96,6 +105,10 @@ impl ClientBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
/// Include a self-signed cert verifier.
|
||||
/// If you only need a known_hosts file, consider using
|
||||
/// [`crate::certs::file_sscv::FileBasedCertVerifier`],
|
||||
/// it will do all the work for you.
|
||||
pub fn with_selfsigned_cert_verifier(
|
||||
mut self,
|
||||
ss_verifier: impl SelfsignedCertVerifier + 'static,
|
||||
|
@ -104,6 +117,10 @@ impl ClientBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
/// Include a custom TLS cert verifier implementing rustls' [`ServerCertVerifier`].
|
||||
/// Normally need to be used only for [`crate::certs::insecure::AllowAllCertVerifier`].
|
||||
/// Note: the webpki verifier and a self-signed cert verifier are not called
|
||||
/// when a custom verifier is set.
|
||||
pub fn with_custom_verifier(
|
||||
mut self,
|
||||
custom_verifier: impl ServerCertVerifier + 'static,
|
||||
|
@ -112,6 +129,8 @@ impl ClientBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
/// Limit the supported TLS versions list to the specified ones.
|
||||
/// Default is [`rustls::DEFAULT_VERSIONS`].
|
||||
pub fn with_tls_versions(
|
||||
mut self,
|
||||
versions: &'static [&'static SupportedProtocolVersion],
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Everything related to Gemini client except cert verification
|
||||
|
||||
pub mod builder;
|
||||
|
||||
use crate::{error::*, response::Response, status::*};
|
||||
|
@ -21,6 +23,8 @@ pub struct Client {
|
|||
}
|
||||
|
||||
impl Default for Client {
|
||||
/// Create a Client with webpki_roots trust anchors and no client auth cert.
|
||||
/// Will be possibly removed in next versions.
|
||||
fn default() -> Self {
|
||||
let roots =
|
||||
rustls::RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
|
||||
|
@ -32,6 +36,7 @@ impl Default for Client {
|
|||
}
|
||||
|
||||
impl From<rustls::ClientConfig> for Client {
|
||||
/// Create a Client from a Rustls config.
|
||||
#[inline]
|
||||
fn from(config: rustls::ClientConfig) -> Self {
|
||||
Client {
|
||||
|
@ -41,18 +46,30 @@ impl From<rustls::ClientConfig> for Client {
|
|||
}
|
||||
|
||||
impl Client {
|
||||
/// Create a Client with a customized configuration,
|
||||
/// see [`ClientBuilder`] methods.
|
||||
pub fn builder() -> ClientBuilder {
|
||||
ClientBuilder::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Parse the given URL, do some checks,
|
||||
/// take host and port (default is 1965) from the URL
|
||||
/// and perform a Gemini request, returning [`Response`] on success.
|
||||
///
|
||||
/// # Errors
|
||||
/// Everything is converted into [`LibError`].
|
||||
/// - [`InvalidUrl::ParseError`] means that the given URL cannot be parsed.
|
||||
/// - [`InvalidUrl::SchemeNotGemini`] is returned when the scheme is not `gemini://`
|
||||
/// (for proxying use [`Client::request_with_host`]).
|
||||
/// - [`InvalidUrl::UserinfoPresent`] is returned when the URL contains userinfo -- `user:password@` --
|
||||
/// which is forbidden by the Gemini specs.
|
||||
/// - For the rest, see [`Client::request_with_host`].
|
||||
pub async fn request(&self, url_str: &str) -> Result<Response, LibError> {
|
||||
let url = Url::parse(url_str).map_err(InvalidUrl::ParseError)?;
|
||||
// for proxying http(s) through gemini server,
|
||||
// use Client::request_with_host
|
||||
// deny non-Gemini requests
|
||||
if url.scheme() != "gemini" {
|
||||
// deny non-Gemini req
|
||||
return Err(InvalidUrl::SchemeNotGemini.into());
|
||||
}
|
||||
// userinfo (user:pswd@) is not allowed in Gemini
|
||||
|
@ -66,6 +83,21 @@ impl Client {
|
|||
self.request_with_host(url_str, host, port).await
|
||||
}
|
||||
|
||||
/// Perform a Gemini request with the specified host, port and URL.
|
||||
/// Non-`gemini://` URLs is OK if the remote server supports proxying.
|
||||
///
|
||||
/// # Errors
|
||||
/// Everything is converted into [`LibError`].
|
||||
/// - [`InvalidUrl::ConvertError`] is an error while converting
|
||||
/// host and port into [`std::net::SocketAddr`] or [`pki_types::ServerName`].
|
||||
/// - [`std::io::Error`] is returned in nearly all cases:
|
||||
/// could not open a TCP connection, perform a TLS handshake,
|
||||
/// write to or read from the TCP stream.
|
||||
/// Check the inner error if you need to determine what exactly happened
|
||||
/// - [`LibError::StatusOutOfRange`] means that a server returned an incorrect status code
|
||||
/// (less than 10 or greater than 69).
|
||||
/// - [`LibError::MessageNotUtf8`] is returned when metadata (the text after the status code)
|
||||
/// is not in UTF-8 and cannot be converted to string without errors.
|
||||
pub async fn request_with_host(
|
||||
&self,
|
||||
url_str: &str,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
//! Gemini client and server implementaion in async Rust with Tokio and Rustls.
|
||||
//! You probably need [`Client::builder()`]
|
||||
|
||||
pub mod certs;
|
||||
pub mod client;
|
||||
pub mod error;
|
||||
|
|
Loading…
Reference in a new issue