Add doctest and replace Url field with String

This commit is contained in:
Tyler Beckman 2024-10-27 16:51:33 -06:00
parent 70a83d4b9e
commit 03f4151f66
Signed by: Ty
GPG key ID: 2813440C772555A4
3 changed files with 97 additions and 9 deletions

47
Cargo.lock generated
View file

@ -62,6 +62,28 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "async-stream"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-stream-impl"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "atomic-waker" name = "atomic-waker"
version = "1.1.2" version = "1.1.2"
@ -191,6 +213,7 @@ dependencies = [
"serde", "serde",
"sha2", "sha2",
"tokio", "tokio",
"tokio-test",
"x509-parser", "x509-parser",
] ]
@ -1235,6 +1258,30 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-stream"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-test"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7"
dependencies = [
"async-stream",
"bytes",
"futures-core",
"tokio",
"tokio-stream",
]
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.12" version = "0.7.12"

View file

@ -18,6 +18,7 @@ base64ct = "1.6.0"
reqwest = { version = "0.12.8", features = ["json"] } reqwest = { version = "0.12.8", features = ["json"] }
serde = { version = "1.0.210", features = ["derive"] } serde = { version = "1.0.210", features = ["derive"] }
tokio = { version = "1.41.0", features = ["rt-multi-thread", "macros"] } tokio = { version = "1.41.0", features = ["rt-multi-thread", "macros"] }
tokio-test = "0.4.4"
[features] [features]
default-features = [] default-features = []

View file

@ -1,6 +1,5 @@
use std::sync::Arc; use std::sync::Arc;
use reqwest::Url;
use responses::{ use responses::{
AddChainRequest, AddChainRequest,
AddChainResponse, AddChainResponse,
@ -21,7 +20,7 @@ pub mod responses;
/// connection-pools to be re-used and will have less overhead between requests. /// connection-pools to be re-used and will have less overhead between requests.
pub struct CtApiClient { pub struct CtApiClient {
inner_client: Arc<reqwest::Client>, inner_client: Arc<reqwest::Client>,
log_url: Url log_url: String
} }
impl CtApiClient { impl CtApiClient {
@ -35,11 +34,21 @@ impl CtApiClient {
/// As this automatically constructs a [`reqwest::Client`], this will error /// As this automatically constructs a [`reqwest::Client`], this will error
/// if the client fails to be created for whatever reason, usually due to it /// if the client fails to be created for whatever reason, usually due to it
/// being unable to find TLS configuration and root store for the platform. /// being unable to find TLS configuration and root store for the platform.
pub fn new(log_url: Url) -> reqwest::Result<Self> { ///
Ok(Self { /// ## Example
inner_client: Arc::new(reqwest::Client::builder().https_only(true).build()?), /// ```
log_url /// use ct::api::CtApiClient;
}) ///
/// let client = CtApiClient::new("https://oak.ct.letsencrypt.org/2025h2")
/// .expect("Should construct properly");
///
/// // Use constructed client here
/// ```
pub fn new(log_url: &str) -> reqwest::Result<Self> {
Ok(Self::new_with_client(
log_url,
Arc::new(reqwest::Client::builder().https_only(true).build()?)
))
} }
/// Creates a new [`CtApiClient`] given a specific log URL and /// Creates a new [`CtApiClient`] given a specific log URL and
@ -47,10 +56,25 @@ impl CtApiClient {
/// log uses one. Anything besides a scheme, host information (ip/port), /// log uses one. Anything besides a scheme, host information (ip/port),
/// and a standard path is not supported and will likely cause requests to /// and a standard path is not supported and will likely cause requests to
/// fail. /// fail.
pub fn new_with_client(log_url: Url, inner_client: Arc<reqwest::Client>) -> Self { ///
/// ## Example
/// ```
/// use std::sync::Arc;
///
/// use ct::api::CtApiClient;
///
/// let existing_client = reqwest::Client::new();
/// let client = CtApiClient::new_with_client(
/// "https://oak.ct.letsencrypt.org/2025h2",
/// Arc::new(existing_client)
/// );
///
/// // Use constructed client here
/// ```
pub fn new_with_client(log_url: &str, inner_client: Arc<reqwest::Client>) -> Self {
Self { Self {
inner_client, inner_client,
log_url log_url: log_url.to_owned()
} }
} }
@ -225,6 +249,22 @@ impl CtApiClient {
/// invalid domain, for example), or if the CT log gave a 4xx/5xx response. /// invalid domain, for example), or if the CT log gave a 4xx/5xx response.
/// The CT log may error the response if it doesn't allow invalid bounds and /// The CT log may error the response if it doesn't allow invalid bounds and
/// the start and end parameters were specified incorrectly. /// the start and end parameters were specified incorrectly.
///
/// ## Example
/// ```
/// use ct::api::CtApiClient;
///
/// let client = CtApiClient::new("https://oak.ct.letsencrypt.org/2025h2")
/// .expect("Should construct properly");
///
/// tokio_test::block_on(async move {
/// let result = client
/// .get_log_entries(0, 9)
/// .await
/// .expect("Request should succeed");
/// assert_eq!(result.entries.len(), 10, "Log should return 10 entries");
/// })
/// ```
pub async fn get_log_entries( pub async fn get_log_entries(
&self, &self,
start: u64, start: u64,