Skip to content

Commit

Permalink
return proper 404 when layer not found
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Mar 7, 2024
1 parent 8db3a23 commit 970afca
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 17 deletions.
2 changes: 1 addition & 1 deletion crates/rattler_networking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ async-trait = { workspace = true }
base64 = { workspace = true }
dirs = { workspace = true }
fslock = { workspace = true }
http = "1.1.0"
http = "0.2"
itertools = { workspace = true }
keyring = { workspace = true }
lazy_static = { workspace = true }
Expand Down
57 changes: 41 additions & 16 deletions crates/rattler_networking/src/mirror_middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,32 @@ use std::{
},
};

use http::StatusCode;
use reqwest::{
header::{ACCEPT, AUTHORIZATION},
Request, Response,
Request, Response, ResponseBuilderExt,
};
use reqwest_middleware::{Middleware, Next, Result};
use serde::Deserialize;
use task_local_extensions::Extensions;
use url::Url;

#[allow(dead_code)]
/// Settings for the specific mirror (e.g. no zstd or bz2 support)
struct MirrorSettings {
no_zstd: bool,
no_bz2: bool,
no_gz: bool,
max_failures: Option<usize>,
}

#[allow(dead_code)]
struct MirrorState {
url: Url,

failures: AtomicUsize,

settings: MirrorSettings,
}

impl MirrorState {
Expand Down Expand Up @@ -50,6 +63,12 @@ impl MirrorMiddleware {
MirrorState {
url: Url::parse(&url).unwrap(),
failures: AtomicUsize::new(0),
settings: MirrorSettings {
no_zstd: false,
no_bz2: false,
no_gz: false,
max_failures: Some(3),
},
}
})
.collect();
Expand Down Expand Up @@ -139,6 +158,16 @@ struct OCIToken {
token: String,
}

pub(crate) fn create_404_response(url: &Url, body: &str) -> Response {
Response::from(
http::response::Builder::new()
.status(StatusCode::NOT_FOUND)
.url(url.clone())
.body(body.to_string())
.unwrap(),
)
}

// [oci://ghcr.io/channel-mirrors/conda-forge]/[osx-arm64/xtensor]
async fn get_token(url: &Url, action: OciAction) -> Result<String> {
let token_url: String = format!(
Expand Down Expand Up @@ -186,9 +215,9 @@ fn reverse_version_build_tag(tag: &str) -> String {
}

fn version_build_tag(tag: &str) -> String {
tag.replace("+", "__p__")
.replace("!", "__e__")
.replace("=", "__eq__")
tag.replace('+', "__p__")
.replace('!', "__e__")
.replace('=', "__eq__")
}

/// We reimplement some logic from rattler here because we don't want to introduce cyclic dependencies
Expand Down Expand Up @@ -227,7 +256,7 @@ fn package_to_tag(url: &Url) -> OciTagMediaType {
}
}

if computed_filename.starts_with("_") {
if computed_filename.starts_with('_') {
computed_filename = format!("zzz{computed_filename}");
}

Expand Down Expand Up @@ -276,7 +305,7 @@ impl Middleware for OciMiddleware {
let token = if let Some(token) = token {
token
} else {
let token = get_token(&url, OciAction::Pull).await?;
let token = get_token(url, OciAction::Pull).await?;
self.token_cache
.lock()
.unwrap()
Expand All @@ -295,7 +324,7 @@ impl Middleware for OciMiddleware {
.get("X-ExpectedSha256")
.map(|s| s.to_str().unwrap().to_string())
{
*req.url_mut() = oci_url_with_hash(&url, &expected_sha_hash);
*req.url_mut() = oci_url_with_hash(url, &expected_sha_hash);
next.run(req, extensions).await
} else {
// get the tag from the URL
Expand All @@ -315,11 +344,7 @@ impl Middleware for OciMiddleware {
.await
.map_err(reqwest_middleware::Error::Reqwest)?;

let manifest_string = manifest.text().await?;
tracing::info!("{}", manifest_string);
let manifest: Manifest = serde_json::from_str(&manifest_string).unwrap();

tracing::info!("{:?}", oci_info);
let manifest: Manifest = manifest.json().await?;

let layer = if let Some(layer) = manifest
.layers
Expand All @@ -328,10 +353,10 @@ impl Middleware for OciMiddleware {
{
layer
} else {
// TODO it would be much better to return a 404 here
return Err(reqwest_middleware::Error::Middleware(anyhow::anyhow!(
"No layer found with the expected media type".to_string()
)));
return Ok(create_404_response(
url,
"No layer available for media type",
));
};

let layer_url = format!(
Expand Down

0 comments on commit 970afca

Please sign in to comment.