async fn auth(
        &mut self,
        image: &Reference,
        authentication: &RegistryAuth,
    ) -> anyhow::Result<()> {
        debug!("Authorzing for image: {:?}", image);
        // The version request will tell us where to go.
        let url = format!(
            "{}://{}/v2/",
            self.config.protocol.scheme_for(image.registry()),
            image.registry()
        );
        let res = self.client.get(&url).send().await?;
        let dist_hdr = match res.headers().get(reqwest::header::WWW_AUTHENTICATE) {
            Some(h) => h,
            None => return Ok(()),
        };

        let auth = WwwAuthenticate::parse_header(&dist_hdr.as_bytes().into())?;
        // If challenge_opt is not set it means that no challenge was present, even though the header
        // was present. Since we do not handle basic auth, it could be the case that the upstream service
        // is in compatibility mode with a Docker v1 registry.
        let challenge_opt = match auth.get::<BearerChallenge>() {
            Some(co) => co,
            None => return Ok(()),
        };

        // Right now, we do read-only auth.
        let pull_perms = format!("repository:{}:pull", image.repository());
        let challenge = &challenge_opt[0];
        let realm = challenge.realm.as_ref().unwrap();
        let service = challenge.service.as_ref().unwrap();

        // TODO: At some point in the future, we should support sending a secret to the
        // server for auth. This particular workflow is for read-only public auth.
        debug!("Making authentication call to {}", realm);
        let auth_res = self
            .client
            .get(realm)
            .query(&[("service", service), ("scope", &pull_perms)])
            .apply_authentication(authentication)
            .send()
            .await?;

        match auth_res.status() {
            reqwest::StatusCode::OK => {
                let text = auth_res.text().await?;
                debug!("Received response from auth request: {}", text);
                let token: RegistryToken = serde_json::from_str(&text)
                    .context("Failed to decode registry token from auth request")?;
                debug!("Succesfully authorized for image '{:?}'", image);
                self.tokens.insert(image.registry().to_owned(), token);
                Ok(())
            }
            _ => {
                let reason = auth_res.text().await?;
                debug!("Failed to authenticate for image '{:?}': {}", image, reason);
                Err(anyhow::anyhow!("failed to authenticate: {}", reason))
            }
        }
    }
/// Perform an OAuth v2 auth request if necessary.
///
/// This performs authorization and then stores the token internally to be used
/// on other requests.
Perform an OAuth v2 auth request if necessary.
This performs authorization and then stores the token internally to be used
on other requests.
Perform an OAuth v2 auth request if necessary . This performs authorization and then stores the token internally to be used on other requests .
async fn auth(
        &mut self,
        image: &Reference,
        authentication: &RegistryAuth,
    ) -> anyhow::Result<()> {
        debug!("Authorzing for image: {:?}", image);
        // The version request will tell us where to go.
        let url = format!(
            "{}://{}/v2/",
            self.config.protocol.scheme_for(image.registry()),
            image.registry()
        );
        let res = self.client.get(&url).send().await?;
        let dist_hdr = match res.headers().get(reqwest::header::WWW_AUTHENTICATE) {
            Some(h) => h,
            None => return Ok(()),
        };
        let auth = WwwAuthenticate::parse_header(&dist_hdr.as_bytes().into())?;
        // If challenge_opt is not set it means that no challenge was present, even though the header
        // was present. Since we do not handle basic auth, it could be the case that the upstream service
        // is in compatibility mode with a Docker v1 registry.
        let challenge_opt = match auth.get::<BearerChallenge>() {
            Some(co) => co,
            None => return Ok(()),
        };
        // Right now, we do read-only auth.
        let pull_perms = format!("repository:{}:pull", image.repository());
        let challenge = &challenge_opt[0];
        let realm = challenge.realm.as_ref().unwrap();
        let service = challenge.service.as_ref().unwrap();
        // TODO: At some point in the future, we should support sending a secret to the
        // server for auth. This particular workflow is for read-only public auth.
        debug!("Making authentication call to {}", realm);
        let auth_res = self
            .client
            .get(realm)
            .query(&[("service", service), ("scope", &pull_perms)])
            .apply_authentication(authentication)
            .send()
            .await?;
        match auth_res.status() {
            reqwest::StatusCode::OK => {
                let text = auth_res.text().await?;
                debug!("Received response from auth request: {}", text);
                let token: RegistryToken = serde_json::from_str(&text)
                    .context("Failed to decode registry token from auth request")?;
                debug!("Succesfully authorized for image '{:?}'", image);
                self.tokens.insert(image.registry().to_owned(), token);
                Ok(())
            }
            _ => {
                let reason = auth_res.text().await?;
                debug!("Failed to authenticate for image '{:?}': {}", image, reason);
                Err(anyhow::anyhow!("failed to authenticate: {}", reason))
            }
        }
    }
async fn auth ( & mut self , image : & Reference , authentication : & RegistryAuth , ) -> anyhow :: Result < ( ) > { debug ! ( " " image ) ; // The version request will tell us where to go. let url = format ! ( " " self config protocol scheme_for ( image registry ( ) ) image registry ( ) ) ; let res = self . client . get ( & url ) . send ( ) . await ? ; let dist_hdr = match res . headers ( ) . get ( reqwest :: header :: WWW_AUTHENTICATE ) { Some ( h ) => h , None => return Ok ( ( ) ) , } ; let auth = WwwAuthenticate :: parse_header ( & dist_hdr . as_bytes ( ) . into ( ) ) ? ; // If challenge_opt is not set it means that no challenge was present, even though the header // was present. Since we do not handle basic auth, it could be the case that the upstream service // is in compatibility mode with a Docker v1 registry. let challenge_opt = match auth . get :: < BearerChallenge > ( ) { Some ( co ) => co , None => return Ok ( ( ) ) , } ; // Right now, we do read-only auth. let pull_perms = format ! ( " " image repository ( ) ) ; let challenge = & challenge_opt [ 0 ] ; let realm = challenge . realm . as_ref ( ) . unwrap ( ) ; let service = challenge . service . as_ref ( ) . unwrap ( ) ; // TODO: At some point in the future, we should support sending a secret to the // server for auth. This particular workflow is for read-only public auth. debug ! ( " " realm ) ; let auth_res = self . client . get ( realm ) . query ( & [ ( " " , service ) , ( " " , & pull_perms ) ] ) . apply_authentication ( authentication ) . send ( ) . await ? ; match auth_res . status ( ) { reqwest :: StatusCode :: OK => { let text = auth_res . text ( ) . await ? ; debug ! ( " " text ) ; let token : RegistryToken = serde_json :: from_str ( & text ) . context ( " " ) ? ; debug ! ( " " image ) ; self . tokens . insert ( image . registry ( ) . to_owned ( ) , token ) ; Ok ( ( ) ) } _ => { let reason = auth_res . text ( ) . await ? ; debug ! ( " " image reason ) ; Err ( anyhow :: anyhow ! ( " " reason ) ) } } }
Perform an OAuth v2 auth request if necessary.
Perform an OAuth v2 auth request if necessary .
&mut self
image
&Reference
authentication
&RegistryAuth
&mut self
image
&Reference
authentication
&RegistryAuth