async fn md_service(
    req: HttpRequest,
    path: web::Path<MdPathArgs>,
    gs: web::Data<Arc<GlobalState>>,
) -> WebResult<HttpResponse> {
    let req_start = utils::Timer::start();
    let peer_addr = req
        .connection_info()
        .realip_remote_addr()
        .map(|x| x.to_string())
        .unwrap_or_else(|| "-".to_string());

    // debug log the User-Agent header (or '-' if it isn't provided`)
    if log::log_enabled!(log::Level::Debug) {
        let user_agent = req
            .headers()
            .get(http::header::USER_AGENT)
            .and_then(|x| x.to_str().ok());
        log::debug!("({}) User-Agent: {}", peer_addr, user_agent.unwrap_or("-"));
    }

    // stop early if archive type is not valid
    if path.archive_type != "data" && path.archive_type != "data-saver" {
        let fmt = format!(
            "invalid archive type. must be one of {:?}",
            ["data", "data-saver"]
        );
        gs.metrics.dropped_requests_total.inc();
        return Err(error::ErrorNotFound(fmt));
    }
    let saver = path.archive_type == "data-saver";

    // verify the token provided in the request url if verify tokens is enabled
    if !gs.config.skip_tokens {
        // unlock verifier mutex
        let verifier = gs.verifier.load();

        match path
            .token
            .as_ref()
            .map(|token| verifier.verify_url_token(token, &path.chap_hash))
        {
            // result is good, so bypass
            Some(Ok(_)) => {}

            // there was an error with the token, so transform into response and return
            Some(Err(e)) => {
                log::warn!("({}) error verifying token in URL ({})", peer_addr, e);
                gs.metrics.dropped_requests_total.inc();
                return Err(e.into());
            }

            // no token was even provided, so just say request is unauthorized
            None => {
                gs.metrics.dropped_requests_total.inc();
                return Err(error::ErrorUnauthorized("no token provided"));
            }
        }
    }

    // increment request counter
    // only count requests if they've made it past token verification
    gs.request_counter.fetch_add(1, atomic::Ordering::Relaxed);

    // respond using CacheResponder, which will handle cache HITs and MISSes
    let args = path.into_inner();
    let cache_key = ImageKey::new(args.chap_hash, args.image, saver);
    Ok(handler::response_from_cache(&peer_addr, &req, &gs, cache_key, req_start).await)
}
/// Request handler for the Actix web server
///
/// This is the main portion of the program, as it takes requests, verifies tokens, and then
/// interacts with the cache to stream the image to the client. However, most of this work is
/// offloaded to other modules.
///
/// - **Token Verification** is handled by the `tokens.rs` file ([`TokenVerifier`])
/// - **Cache HIT/MISS Logic** is handled by the `handler.rs` file
///
/// [`TokenVerifier`]: crate::tokens::TokenVerifier
Request handler for the Actix web server
This is the main portion of the program, as it takes requests, verifies tokens, and then
interacts with the cache to stream the image to the client. However, most of this work is
offloaded to other modules.




Request handler for the Actix web server This is the main portion of the program as it takes requests verifies tokens and then interacts with the cache to stream the image to the client . However most of this work is offloaded to other modules .
async fn md_service(
    req: HttpRequest,
    path: web::Path<MdPathArgs>,
    gs: web::Data<Arc<GlobalState>>,
) -> WebResult<HttpResponse> {
    let req_start = utils::Timer::start();
    let peer_addr = req
        .connection_info()
        .realip_remote_addr()
        .map(|x| x.to_string())
        .unwrap_or_else(|| "-".to_string());
    // debug log the User-Agent header (or '-' if it isn't provided`)
    if log::log_enabled!(log::Level::Debug) {
        let user_agent = req
            .headers()
            .get(http::header::USER_AGENT)
            .and_then(|x| x.to_str().ok());
        log::debug!("({}) User-Agent: {}", peer_addr, user_agent.unwrap_or("-"));
    }
    // stop early if archive type is not valid
    if path.archive_type != "data" && path.archive_type != "data-saver" {
        let fmt = format!(
            "invalid archive type. must be one of {:?}",
            ["data", "data-saver"]
        );
        gs.metrics.dropped_requests_total.inc();
        return Err(error::ErrorNotFound(fmt));
    }
    let saver = path.archive_type == "data-saver";
    // verify the token provided in the request url if verify tokens is enabled
    if !gs.config.skip_tokens {
        // unlock verifier mutex
        let verifier = gs.verifier.load();
        match path
            .token
            .as_ref()
            .map(|token| verifier.verify_url_token(token, &path.chap_hash))
        {
            // result is good, so bypass
            Some(Ok(_)) => {}
            // there was an error with the token, so transform into response and return
            Some(Err(e)) => {
                log::warn!("({}) error verifying token in URL ({})", peer_addr, e);
                gs.metrics.dropped_requests_total.inc();
                return Err(e.into());
            }
            // no token was even provided, so just say request is unauthorized
            None => {
                gs.metrics.dropped_requests_total.inc();
                return Err(error::ErrorUnauthorized("no token provided"));
            }
        }
    }
    // increment request counter
    // only count requests if they've made it past token verification
    gs.request_counter.fetch_add(1, atomic::Ordering::Relaxed);
    // respond using CacheResponder, which will handle cache HITs and MISSes
    let args = path.into_inner();
    let cache_key = ImageKey::new(args.chap_hash, args.image, saver);
    Ok(handler::response_from_cache(&peer_addr, &req, &gs, cache_key, req_start).await)
}
async fn md_service ( req : HttpRequest , path : web :: Path < MdPathArgs > , gs : web :: Data < Arc < GlobalState > > , ) -> WebResult < HttpResponse > { let req_start = utils :: Timer :: start ( ) ; let peer_addr = req . connection_info ( ) . realip_remote_addr ( ) . map ( | x | x . to_string ( ) ) . unwrap_or_else ( | | " " . to_string ( ) ) ; // debug log the User-Agent header (or '-' if it isn't provided`) if log :: log_enabled ! ( log Level Debug ) { let user_agent = req . headers ( ) . get ( http :: header :: USER_AGENT ) . and_then ( | x | x . to_str ( ) . ok ( ) ) ; log :: debug ! ( " " peer_addr user_agent unwrap_or ( " " ) ) ; } // stop early if archive type is not valid if path . archive_type != " " && path . archive_type != " " { let fmt = format ! ( " " [ " " " " ] ) ; gs . metrics . dropped_requests_total . inc ( ) ; return Err ( error :: ErrorNotFound ( fmt ) ) ; } let saver = path . archive_type == " " ; // verify the token provided in the request url if verify tokens is enabled if ! gs . config . skip_tokens { // unlock verifier mutex let verifier = gs . verifier . load ( ) ; match path . token . as_ref ( ) . map ( | token | verifier . verify_url_token ( token , & path . chap_hash ) ) { // result is good, so bypass Some ( Ok ( _ ) ) => { } // there was an error with the token, so transform into response and return Some ( Err ( e ) ) => { log :: warn ! ( " " peer_addr e ) ; gs . metrics . dropped_requests_total . inc ( ) ; return Err ( e . into ( ) ) ; } // no token was even provided, so just say request is unauthorized None => { gs . metrics . dropped_requests_total . inc ( ) ; return Err ( error :: ErrorUnauthorized ( " " ) ) ; } } } // increment request counter // only count requests if they've made it past token verification gs . request_counter . fetch_add ( 1 , atomic :: Ordering :: Relaxed ) ; // respond using CacheResponder, which will handle cache HITs and MISSes let args = path . into_inner ( ) ; let cache_key = ImageKey :: new ( args . chap_hash , args . image , saver ) ; Ok ( handler :: response_from_cache ( & peer_addr , & req , & gs , cache_key , req_start ) . await ) }
Request handler for the Actix web server
This is the main portion of the program, as it takes requests, verifies tokens, and then
interacts with the cache to stream the image to the client.
Request handler for the Actix web server This is the main portion of the program as it takes requests verifies tokens and then interacts with the cache to stream the image to the client .
req
HttpRequest
path
web::Path<MdPathArgs>
gs
web::Data<Arc<GlobalState>>