mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-26 12:09:12 +00:00
Support for wildcard in UV_INSECURE_HOST (#8052)
Allow '*' as a value to match all hosts, and provide `reqwest_blocking_get` for uv tests, so that they also respect UV_INSECURE_HOST (since they respect `ALL_PROXY`). This lets those tests pass with a forward proxy - we can think about setting a root certificate later so that we don't need to disable certificate verification at all. --- I tested this locally by running: ```bash GIT_SSL_NO_VERIFY=true ALL_PROXY=localhost:8080 UV_INSECURE_HOST="*" cargo nextest run sync_wheel_path_source_error ``` With my forward proxy showing: ``` 2024-10-09T18:20:16.300188Z INFO fopro: Proxied GETcc2fedbd88/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl
(headers 480.024958ms + body 92.345666ms) 2024-10-09T18:20:16.913298Z INFO fopro: Proxied GET https://pypi.org/simple/pycparser/ (headers 509.664834ms + body 269.291µs) 2024-10-09T18:20:17.383975Z INFO fopro: Proxied GET5f610ebe42/pycparser-2.21-py2.py3-none-any.whl.metadata
(headers 443.184208ms + body 2.094792ms) ```
This commit is contained in:
parent
9351652e32
commit
a3b11dacb8
8 changed files with 137 additions and 81 deletions
|
@ -2,35 +2,40 @@ use serde::{Deserialize, Deserializer};
|
|||
use std::str::FromStr;
|
||||
use url::Url;
|
||||
|
||||
/// A trusted host, which could be a host or a host-port pair.
|
||||
/// A host specification (wildcard, or host, with optional scheme and/or port) for which
|
||||
/// certificates are not verified when making HTTPS requests.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct TrustedHost {
|
||||
pub enum TrustedHost {
|
||||
Wildcard,
|
||||
Host {
|
||||
scheme: Option<String>,
|
||||
host: String,
|
||||
port: Option<u16>,
|
||||
},
|
||||
}
|
||||
|
||||
impl TrustedHost {
|
||||
/// Returns `true` if the [`Url`] matches this trusted host.
|
||||
pub fn matches(&self, url: &Url) -> bool {
|
||||
if self
|
||||
.scheme
|
||||
.as_ref()
|
||||
.is_some_and(|scheme| scheme != url.scheme())
|
||||
{
|
||||
match self {
|
||||
TrustedHost::Wildcard => true,
|
||||
TrustedHost::Host { scheme, host, port } => {
|
||||
if scheme.as_ref().is_some_and(|scheme| scheme != url.scheme()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.port.is_some_and(|port| url.port() != Some(port)) {
|
||||
if port.is_some_and(|port| url.port() != Some(port)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if Some(self.host.as_ref()) != url.host_str() {
|
||||
if Some(host.as_str()) != url.host_str() {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for TrustedHost {
|
||||
|
@ -48,7 +53,7 @@ impl<'de> Deserialize<'de> for TrustedHost {
|
|||
serde_untagged::UntaggedEnumVisitor::new()
|
||||
.string(|string| TrustedHost::from_str(string).map_err(serde::de::Error::custom))
|
||||
.map(|map| {
|
||||
map.deserialize::<Inner>().map(|inner| TrustedHost {
|
||||
map.deserialize::<Inner>().map(|inner| TrustedHost::Host {
|
||||
scheme: inner.scheme,
|
||||
host: inner.host,
|
||||
port: inner.port,
|
||||
|
@ -80,6 +85,10 @@ impl std::str::FromStr for TrustedHost {
|
|||
type Err = TrustedHostError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s == "*" {
|
||||
return Ok(Self::Wildcard);
|
||||
}
|
||||
|
||||
// Detect scheme.
|
||||
let (scheme, s) = if let Some(s) = s.strip_prefix("https://") {
|
||||
(Some("https".to_string()), s)
|
||||
|
@ -105,21 +114,28 @@ impl std::str::FromStr for TrustedHost {
|
|||
.transpose()
|
||||
.map_err(|_| TrustedHostError::InvalidPort(s.to_string()))?;
|
||||
|
||||
Ok(Self { scheme, host, port })
|
||||
Ok(Self::Host { scheme, host, port })
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for TrustedHost {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
if let Some(scheme) = &self.scheme {
|
||||
write!(f, "{}://{}", scheme, self.host)?;
|
||||
match self {
|
||||
TrustedHost::Wildcard => {
|
||||
write!(f, "*")?;
|
||||
}
|
||||
TrustedHost::Host { scheme, host, port } => {
|
||||
if let Some(scheme) = &scheme {
|
||||
write!(f, "{scheme}://{host}")?;
|
||||
} else {
|
||||
write!(f, "{}", self.host)?;
|
||||
write!(f, "{host}")?;
|
||||
}
|
||||
|
||||
if let Some(port) = self.port {
|
||||
if let Some(port) = port {
|
||||
write!(f, ":{port}")?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
#[test]
|
||||
fn parse() {
|
||||
assert_eq!(
|
||||
"*".parse::<super::TrustedHost>().unwrap(),
|
||||
super::TrustedHost::Wildcard
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"example.com".parse::<super::TrustedHost>().unwrap(),
|
||||
super::TrustedHost {
|
||||
super::TrustedHost::Host {
|
||||
scheme: None,
|
||||
host: "example.com".to_string(),
|
||||
port: None
|
||||
|
@ -11,7 +16,7 @@ fn parse() {
|
|||
|
||||
assert_eq!(
|
||||
"example.com:8080".parse::<super::TrustedHost>().unwrap(),
|
||||
super::TrustedHost {
|
||||
super::TrustedHost::Host {
|
||||
scheme: None,
|
||||
host: "example.com".to_string(),
|
||||
port: Some(8080)
|
||||
|
@ -20,7 +25,7 @@ fn parse() {
|
|||
|
||||
assert_eq!(
|
||||
"https://example.com".parse::<super::TrustedHost>().unwrap(),
|
||||
super::TrustedHost {
|
||||
super::TrustedHost::Host {
|
||||
scheme: Some("https".to_string()),
|
||||
host: "example.com".to_string(),
|
||||
port: None
|
||||
|
@ -31,7 +36,7 @@ fn parse() {
|
|||
"https://example.com/hello/world"
|
||||
.parse::<super::TrustedHost>()
|
||||
.unwrap(),
|
||||
super::TrustedHost {
|
||||
super::TrustedHost::Host {
|
||||
scheme: Some("https".to_string()),
|
||||
host: "example.com".to_string(),
|
||||
port: None
|
||||
|
|
|
@ -14,11 +14,13 @@ use assert_fs::assert::PathAssert;
|
|||
use assert_fs::fixture::{ChildPath, PathChild, PathCopy, PathCreateDir, SymlinkToFile};
|
||||
use base64::{prelude::BASE64_STANDARD as base64, Engine};
|
||||
use etcetera::BaseStrategy;
|
||||
use futures::StreamExt;
|
||||
use indoc::formatdoc;
|
||||
use itertools::Itertools;
|
||||
use predicates::prelude::predicate;
|
||||
use regex::Regex;
|
||||
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use uv_cache::Cache;
|
||||
use uv_fs::Simplified;
|
||||
use uv_python::managed::ManagedPythonInstallations;
|
||||
|
@ -1279,6 +1281,31 @@ pub fn decode_token(content: &[&str]) -> String {
|
|||
token
|
||||
}
|
||||
|
||||
/// Simulates `reqwest::blocking::get` but returns bytes directly, and disables
|
||||
/// certificate verification, passing through the `BaseClient`
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn download_to_disk(url: &str, path: &Path) {
|
||||
let trusted_hosts: Vec<_> = std::env::var("UV_INSECURE_HOST")
|
||||
.unwrap_or_default()
|
||||
.split(' ')
|
||||
.map(|h| uv_configuration::TrustedHost::from_str(h).unwrap())
|
||||
.collect();
|
||||
|
||||
let client = uv_client::BaseClientBuilder::new()
|
||||
.allow_insecure_host(trusted_hosts)
|
||||
.build();
|
||||
let url: reqwest::Url = url.parse().unwrap();
|
||||
let client = client.for_host(&url);
|
||||
let response = client.request(http::Method::GET, url).send().await.unwrap();
|
||||
|
||||
let mut file = tokio::fs::File::create(path).await.unwrap();
|
||||
let mut stream = response.bytes_stream();
|
||||
while let Some(chunk) = stream.next().await {
|
||||
file.write_all(&chunk.unwrap()).await.unwrap();
|
||||
}
|
||||
file.sync_all().await.unwrap();
|
||||
}
|
||||
|
||||
/// Utility macro to return the name of the current function.
|
||||
///
|
||||
/// https://stackoverflow.com/a/40234666/3549270
|
||||
|
|
|
@ -7,7 +7,8 @@ use std::io::BufReader;
|
|||
use url::Url;
|
||||
|
||||
use crate::common::{
|
||||
self, build_vendor_links_url, decode_token, packse_index_url, uv_snapshot, TestContext,
|
||||
self, build_vendor_links_url, decode_token, download_to_disk, packse_index_url, uv_snapshot,
|
||||
TestContext,
|
||||
};
|
||||
use uv_fs::Simplified;
|
||||
|
||||
|
@ -7967,11 +7968,11 @@ fn lock_sources_archive() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download the source.
|
||||
let response =
|
||||
reqwest::blocking::get("https://github.com/user-attachments/files/16592193/workspace.zip")?;
|
||||
let workspace_archive = context.temp_dir.child("workspace.zip");
|
||||
let mut workspace_archive_file = fs_err::File::create(&*workspace_archive)?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut workspace_archive_file)?;
|
||||
download_to_disk(
|
||||
"https://github.com/user-attachments/files/16592193/workspace.zip",
|
||||
&workspace_archive,
|
||||
);
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(&formatdoc! {
|
||||
|
@ -8106,11 +8107,11 @@ fn lock_sources_source_tree() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download the source.
|
||||
let response =
|
||||
reqwest::blocking::get("https://github.com/user-attachments/files/16592193/workspace.zip")?;
|
||||
let workspace_archive = context.temp_dir.child("workspace.zip");
|
||||
let mut workspace_archive_file = fs_err::File::create(&*workspace_archive)?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut workspace_archive_file)?;
|
||||
download_to_disk(
|
||||
"https://github.com/user-attachments/files/16592193/workspace.zip",
|
||||
&workspace_archive,
|
||||
);
|
||||
|
||||
// Unzip the file.
|
||||
let file = fs_err::File::open(&*workspace_archive)?;
|
||||
|
|
|
@ -8,9 +8,9 @@ use anyhow::{bail, Context, Result};
|
|||
use assert_fs::prelude::*;
|
||||
use indoc::indoc;
|
||||
use url::Url;
|
||||
use uv_fs::Simplified;
|
||||
|
||||
use crate::common::{uv_snapshot, TestContext};
|
||||
use crate::common::{download_to_disk, uv_snapshot, TestContext};
|
||||
use uv_fs::Simplified;
|
||||
|
||||
#[test]
|
||||
fn compile_requirements_in() -> Result<()> {
|
||||
|
@ -2592,10 +2592,11 @@ fn compile_wheel_path_dependency() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?;
|
||||
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
||||
let mut flask_wheel_file = fs::File::create(&flask_wheel)?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl",
|
||||
&flask_wheel,
|
||||
);
|
||||
|
||||
let requirements_in = context.temp_dir.child("requirements.in");
|
||||
requirements_in.write_str(&format!(
|
||||
|
@ -2842,10 +2843,11 @@ fn compile_wheel_path_dependency() -> Result<()> {
|
|||
fn compile_source_distribution_path_dependency() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
// Download a source distribution.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz")?;
|
||||
let flask_wheel = context.temp_dir.child("flask-3.0.0.tar.gz");
|
||||
let mut flask_wheel_file = std::fs::File::create(&flask_wheel)?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz",
|
||||
&flask_wheel,
|
||||
);
|
||||
|
||||
let requirements_in = context.temp_dir.child("requirements.in");
|
||||
requirements_in.write_str(&format!(
|
||||
|
@ -3517,10 +3519,11 @@ fn preserve_url() -> Result<()> {
|
|||
fn preserve_project_root() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?;
|
||||
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
||||
let mut flask_wheel_file = std::fs::File::create(flask_wheel)?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl",
|
||||
&flask_wheel,
|
||||
);
|
||||
|
||||
let requirements_in = context.temp_dir.child("requirements.in");
|
||||
requirements_in.write_str("flask @ file://${PROJECT_ROOT}/flask-3.0.0-py3-none-any.whl")?;
|
||||
|
@ -3670,10 +3673,11 @@ fn error_missing_unnamed_env_var() -> Result<()> {
|
|||
fn respect_file_env_var() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?;
|
||||
let flask_wheel = context.temp_dir.child("flask-3.0.0-py3-none-any.whl");
|
||||
let mut flask_wheel_file = std::fs::File::create(flask_wheel)?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut flask_wheel_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl",
|
||||
&flask_wheel,
|
||||
);
|
||||
|
||||
let requirements_in = context.temp_dir.child("requirements.in");
|
||||
requirements_in.write_str("flask @ ${FILE_PATH}")?;
|
||||
|
|
|
@ -12,7 +12,8 @@ use predicates::Predicate;
|
|||
use url::Url;
|
||||
|
||||
use crate::common::{
|
||||
copy_dir_all, site_packages_path, uv_snapshot, venv_to_interpreter, TestContext,
|
||||
copy_dir_all, download_to_disk, site_packages_path, uv_snapshot, venv_to_interpreter,
|
||||
TestContext,
|
||||
};
|
||||
use uv_fs::Simplified;
|
||||
|
||||
|
@ -1069,10 +1070,8 @@ fn install_local_wheel() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
||||
let archive = context.temp_dir.child("tomli-2.0.1-py3-none-any.whl");
|
||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
||||
download_to_disk("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", &archive);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(&format!(
|
||||
|
@ -1208,10 +1207,8 @@ fn mismatched_version() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
||||
let archive = context.temp_dir.child("tomli-3.7.2-py3-none-any.whl");
|
||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
||||
download_to_disk("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", &archive);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(&format!(
|
||||
|
@ -1243,10 +1240,11 @@ fn mismatched_name() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
||||
let archive = context.temp_dir.child("foo-2.0.1-py3-none-any.whl");
|
||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
|
||||
&archive,
|
||||
);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(&format!(
|
||||
|
@ -1279,10 +1277,11 @@ fn install_local_source_distribution() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a source distribution.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/b0/b4/bc2baae3970c282fae6c2cb8e0f179923dceb7eaffb0e76170628f9af97b/wheel-0.42.0.tar.gz")?;
|
||||
let archive = context.temp_dir.child("wheel-0.42.0.tar.gz");
|
||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/b0/b4/bc2baae3970c282fae6c2cb8e0f179923dceb7eaffb0e76170628f9af97b/wheel-0.42.0.tar.gz",
|
||||
&archive,
|
||||
);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(&format!(
|
||||
|
@ -1639,10 +1638,11 @@ fn install_path_source_dist_cached() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a source distribution.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz")?;
|
||||
let archive = context.temp_dir.child("source_distribution-0.0.1.tar.gz");
|
||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz",
|
||||
&archive,
|
||||
);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(&format!(
|
||||
|
@ -1734,10 +1734,11 @@ fn install_path_built_dist_cached() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
||||
let archive = context.temp_dir.child("tomli-2.0.1-py3-none-any.whl");
|
||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
|
||||
&archive,
|
||||
);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
let url = Url::from_file_path(archive.path()).unwrap();
|
||||
|
|
|
@ -3552,12 +3552,12 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
|||
index_strategy: FirstIndex,
|
||||
keyring_provider: Disabled,
|
||||
allow_insecure_host: [
|
||||
TrustedHost {
|
||||
Host {
|
||||
scheme: None,
|
||||
host: "google.com",
|
||||
port: None,
|
||||
},
|
||||
TrustedHost {
|
||||
Host {
|
||||
scheme: None,
|
||||
host: "example.com",
|
||||
port: None,
|
||||
|
|
|
@ -2,10 +2,11 @@ use anyhow::Result;
|
|||
use assert_cmd::prelude::*;
|
||||
use assert_fs::{fixture::ChildPath, prelude::*};
|
||||
use insta::assert_snapshot;
|
||||
|
||||
use predicates::prelude::predicate;
|
||||
use tempfile::tempdir_in;
|
||||
|
||||
use crate::common::{uv_snapshot, venv_bin_path, TestContext};
|
||||
use predicates::prelude::predicate;
|
||||
use crate::common::{download_to_disk, uv_snapshot, venv_bin_path, TestContext};
|
||||
|
||||
#[test]
|
||||
fn sync() -> Result<()> {
|
||||
|
@ -2309,12 +2310,13 @@ fn sync_wheel_path_source_error() -> Result<()> {
|
|||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download a wheel.
|
||||
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl")?;
|
||||
let archive = context
|
||||
.temp_dir
|
||||
.child("cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl");
|
||||
let mut archive_file = fs_err::File::create(archive.path())?;
|
||||
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl",
|
||||
&archive,
|
||||
);
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue