http-cache-ureq 1.0.0-alpha.7

http-cache middleware implementation for ureq
//! Basic HTTP caching with ureq
//!
//! Run with: cargo run --example ureq_basic --features manager-cacache
//!
//! Note: `CACacheManager` delegates to the `cacache` crate, which is compiled
//! with its `tokio-runtime` feature. This example uses smol::block_on for the
//! async body, so we install a tokio runtime alongside and enter its context —
//! that way cacache's `tokio::fs` operations find a reactor while the rest of
//! the example continues to run on smol.

use http_cache_ureq::{CACacheManager, CachedAgent};
use std::time::Instant;
use wiremock::{matchers::method, Mock, MockServer, ResponseTemplate};

fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let tokio_rt = tokio::runtime::Runtime::new()?;
    let _tokio_guard = tokio_rt.enter();
    smol::block_on(async {
        // Setup mock server with cacheable response
        let mock_server = MockServer::start().await;
        Mock::given(method("GET"))
            .respond_with(
                ResponseTemplate::new(200)
                    .set_body_string("Hello from cached response!")
                    .append_header("cache-control", "max-age=300, public")
                    .append_header("content-type", "text/plain"),
            )
            .mount(&mock_server)
            .await;

        let cache_dir = tempfile::tempdir().unwrap();
        let cache_manager =
            CACacheManager::new(cache_dir.path().to_path_buf(), true);
        let client =
            CachedAgent::builder().cache_manager(cache_manager).build()?;

        let url = format!("{}/", mock_server.uri());

        println!("Testing HTTP caching with ureq...");

        // First request
        let start = Instant::now();
        let response = client.get(&url).call().await?;

        println!("First request: {:?}", start.elapsed());
        println!("Status: {}", response.status());

        // Check cache headers after first request
        if let Some(x_cache) = response.header("x-cache") {
            println!("Cache header x-cache: {}", x_cache);
        }
        if let Some(x_cache_lookup) = response.header("x-cache-lookup") {
            println!("Cache header x-cache-lookup: {}", x_cache_lookup);
        }

        println!();

        // Second request
        let start = Instant::now();
        let response = client.get(&url).call().await?;

        println!("Second request: {:?}", start.elapsed());
        println!("Status: {}", response.status());

        // Check cache headers after second request
        if let Some(x_cache) = response.header("x-cache") {
            println!("Cache header x-cache: {}", x_cache);
        }
        if let Some(x_cache_lookup) = response.header("x-cache-lookup") {
            println!("Cache header x-cache-lookup: {}", x_cache_lookup);
        }

        Ok(())
    })
}