[go: nahoru, domu]

Skip to content

Commit

Permalink
fix(oci-distribution): do not set Accept header on all requests
Browse files Browse the repository at this point in the history
When issuing requests to the OCI registry, only set the `Accept`
header on endpoints that will use it in order to produce a response
taking this parameter into account.

The `oci-distribution` crate is currently having issues to push to the
JFrog Artifactory registry, because this registry is strict in what
headers are provided. This behavior is not specified in the OCI
distribution specification, so the OCI registry implementors are open
to behave in different ways.

In any case, sending the `Accept` header on all requests with a fixed
set of MIME types can be improved, and this change applies this header
only on the requests that are expecting the server to reply with one
of the given MIME types.

Signed-off-by: Rafael Fernández López <rfernandezlopez@suse.com>
  • Loading branch information
ereslibre committed Oct 5, 2021
1 parent 2ec1ee6 commit 13db2f4
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion crates/oci-distribution/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ use tokio::io::{AsyncWrite, AsyncWriteExt};
use tracing::{debug, warn};
use www_authenticate::{Challenge, ChallengeFields, RawChallenge, WwwAuthenticate};

const MIME_TYPES_DISTRIBUTION_MANIFEST: &[&str] = &[
"application/vnd.docker.distribution.manifest.v2+json",
"application/vnd.docker.distribution.manifest.list.v2+json",
"application/vnd.oci.image.manifest.v1+json",
];

/// The data for an image or module.
#[derive(Clone)]
pub struct ImageData {
Expand Down Expand Up @@ -369,6 +375,7 @@ impl Client {
debug!("Pulling image manifest from {}", url);

let res = RequestBuilderWrapper::from_client(self, |client| client.get(&url))
.apply_accept(MIME_TYPES_DISTRIBUTION_MANIFEST)?
.apply_auth(image)?
.into_request_builder()
.send()
Expand Down Expand Up @@ -446,6 +453,7 @@ impl Client {
debug!("Pulling image manifest from {}", url);

let res = RequestBuilderWrapper::from_client(self, |client| client.get(&url))
.apply_accept(MIME_TYPES_DISTRIBUTION_MANIFEST)?
.apply_auth(image)?
.into_request_builder()
.send()
Expand Down Expand Up @@ -555,6 +563,7 @@ impl Client {
) -> anyhow::Result<()> {
let url = self.to_v2_blob_url(&self.get_registry(image), image.repository(), digest);
let mut stream = RequestBuilderWrapper::from_client(self, |client| client.get(&url))
.apply_accept(MIME_TYPES_DISTRIBUTION_MANIFEST)?
.apply_auth(image)?
.into_request_builder()
.send()
Expand Down Expand Up @@ -862,6 +871,19 @@ impl<'a> RequestBuilderWrapper<'a> {

// Composable functions applicable to a `RequestBuilderWrapper`
impl<'a> RequestBuilderWrapper<'a> {
fn apply_accept(&self, accept: &[&str]) -> anyhow::Result<RequestBuilderWrapper> {
let request_builder = self
.request_builder
.try_clone()
.ok_or_else(|| anyhow!("could not clone request builder"))?
.header("Accept", Vec::from(accept).join(", "));

Ok(RequestBuilderWrapper {
client: self.client,
request_builder,
})
}

/// Updates request as necessary for authentication.
///
/// If the struct has Some(bearer), this will insert the bearer token in an
Expand All @@ -870,7 +892,6 @@ impl<'a> RequestBuilderWrapper<'a> {
/// credentials, these will be configured.
fn apply_auth(&self, image: &Reference) -> anyhow::Result<RequestBuilderWrapper> {
let mut headers = HeaderMap::new();
headers.insert("Accept", "application/vnd.docker.distribution.manifest.v2+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.manifest.v1+json".parse().unwrap());

if let Some(token) = self.client.tokens.get(&self.client.get_registry(&image)) {
match token {
Expand Down

0 comments on commit 13db2f4

Please sign in to comment.