mirror of
https://github.com/typst/typst
synced 2025-07-27 14:27:56 +08:00
Merge e2a022ac7ba5f60cdbcc6f526297ffe2449e9a07 into 7278d887cf05fadc9a96478830e5876739b78f53
This commit is contained in:
commit
76ca25c1a8
211
Cargo.lock
generated
211
Cargo.lock
generated
@ -136,6 +136,12 @@ version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3"
|
||||
|
||||
[[package]]
|
||||
name = "biblatex"
|
||||
version = "0.10.0"
|
||||
@ -244,6 +250,12 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.11"
|
||||
@ -471,6 +483,35 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"time",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie_store"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9"
|
||||
dependencies = [
|
||||
"cookie",
|
||||
"document-features",
|
||||
"idna",
|
||||
"indexmap 2.7.1",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"time",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
@ -572,6 +613,16 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||
dependencies = [
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
@ -624,6 +675,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "document-features"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
|
||||
dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
@ -677,16 +737,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_proxy"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a5019be18538406a43b5419a5501461f0c8b49ea7dfda0cfc32f4e51fc44be1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@ -1033,6 +1083,23 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.3"
|
||||
@ -1566,6 +1633,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
@ -1912,6 +1985,15 @@ dependencies = [
|
||||
"ryu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
@ -2287,6 +2369,24 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
|
||||
dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.19"
|
||||
@ -2514,6 +2614,17 @@ version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "socks"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
@ -3065,7 +3176,6 @@ version = "0.13.1"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"ecow",
|
||||
"env_proxy",
|
||||
"fastrand",
|
||||
"flate2",
|
||||
"fontdb",
|
||||
@ -3435,18 +3545,37 @@ checksum = "e9df2af067a7953e9c3831320f35c1cc0600c30d44d9f7a12b01db1cd88d6b47"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "2.12.1"
|
||||
version = "3.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d"
|
||||
checksum = "b7a3e9af6113ecd57b8c63d3cd76a385b2e3881365f1f489e54f49801d0c83ea"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"cookie_store",
|
||||
"der",
|
||||
"flate2",
|
||||
"log",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
"socks",
|
||||
"ureq-proto",
|
||||
"utf-8",
|
||||
"webpki-root-certs 0.26.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ureq-proto"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fadf18427d33828c311234884b7ba2afb57143e6e7e69fda7ee883b624661e36"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3488,6 +3617,12 @@ dependencies = [
|
||||
"xmlwriter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utf16_iter"
|
||||
version = "1.0.5"
|
||||
@ -3665,12 +3800,46 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "0.26.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e"
|
||||
dependencies = [
|
||||
"webpki-root-certs 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01a83f7e1a9f8712695c03eabe9ed3fbca0feff0152f33f12593e5a6303cb1a4"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
@ -3680,6 +3849,12 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
@ -3957,6 +4132,12 @@ dependencies = [
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
version = "0.1.3"
|
||||
|
@ -54,7 +54,6 @@ csv = "1"
|
||||
ctrlc = "3.4.1"
|
||||
dirs = "6"
|
||||
ecow = { version = "0.2", features = ["serde"] }
|
||||
env_proxy = "0.4"
|
||||
fastrand = "2.3"
|
||||
flate2 = "1"
|
||||
fontdb = { version = "0.23", default-features = false }
|
||||
@ -134,7 +133,7 @@ unicode-script = "0.5"
|
||||
unicode-normalization = "0.1.24"
|
||||
unicode-segmentation = "1"
|
||||
unscanny = "0.1"
|
||||
ureq = { version = "2", default-features = false, features = ["native-tls", "gzip", "json"] }
|
||||
ureq = { version = "3", default-features = false, features = ["native-tls", "gzip", "json", "socks-proxy"] }
|
||||
usvg = { version = "0.45", default-features = false, features = ["text"] }
|
||||
utf8_iter = "1.0.4"
|
||||
walkdir = "2"
|
||||
|
@ -145,10 +145,10 @@ impl Release {
|
||||
};
|
||||
|
||||
match downloader.download(&url) {
|
||||
Ok(response) => response.into_json().map_err(|err| {
|
||||
Ok(mut response) => response.body_mut().read_json().map_err(|err| {
|
||||
eco_format!("failed to parse release information ({err})")
|
||||
}),
|
||||
Err(ureq::Error::Status(404, _)) => {
|
||||
Err(ureq::Error::StatusCode(404)) => {
|
||||
bail!("release not found (searched at {url})")
|
||||
}
|
||||
Err(err) => bail!("failed to download release ({err})"),
|
||||
@ -175,7 +175,7 @@ impl Release {
|
||||
&mut PrintDownload("release"),
|
||||
) {
|
||||
Ok(data) => data,
|
||||
Err(ureq::Error::Status(404, _)) => {
|
||||
Err(ureq::Error::StatusCode(404)) => {
|
||||
bail!("asset not found (searched for {})", asset.name);
|
||||
}
|
||||
Err(err) => bail!("failed to download asset ({err})"),
|
||||
|
@ -18,7 +18,6 @@ typst-timing = { workspace = true }
|
||||
typst-utils = { workspace = true }
|
||||
dirs = { workspace = true, optional = true }
|
||||
ecow = { workspace = true }
|
||||
env_proxy = { workspace = true, optional = true }
|
||||
fastrand = { workspace = true, optional = true }
|
||||
flate2 = { workspace = true, optional = true }
|
||||
fontdb = { workspace = true, optional = true }
|
||||
@ -41,7 +40,7 @@ default = ["fonts", "packages"]
|
||||
fonts = ["dep:fontdb", "fontdb/memmap", "fontdb/fontconfig"]
|
||||
|
||||
# Add generic downloading utilities
|
||||
downloads = ["dep:env_proxy", "dep:native-tls", "dep:ureq", "dep:openssl"]
|
||||
downloads = ["dep:native-tls", "dep:ureq", "dep:openssl"]
|
||||
|
||||
# Add package downloading utilities, implies `downloads`
|
||||
packages = ["downloads", "dep:dirs", "dep:flate2", "dep:tar", "dep:fastrand"]
|
||||
|
@ -13,9 +13,8 @@ use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use ecow::EcoString;
|
||||
use native_tls::{Certificate, TlsConnector};
|
||||
use once_cell::sync::OnceCell;
|
||||
use ureq::Response;
|
||||
use ureq::tls::{Certificate, RootCerts, TlsProvider};
|
||||
|
||||
/// Manages progress reporting for downloads.
|
||||
pub trait Progress {
|
||||
@ -57,7 +56,7 @@ pub struct DownloadState {
|
||||
pub struct Downloader {
|
||||
user_agent: EcoString,
|
||||
cert_path: Option<PathBuf>,
|
||||
cert: OnceCell<Certificate>,
|
||||
cert: OnceCell<Certificate<'static>>,
|
||||
}
|
||||
|
||||
impl Downloader {
|
||||
@ -82,7 +81,10 @@ impl Downloader {
|
||||
}
|
||||
|
||||
/// Crates a new downloader with the given user agent and certificate.
|
||||
pub fn with_cert(user_agent: impl Into<EcoString>, cert: Certificate) -> Self {
|
||||
pub fn with_cert(
|
||||
user_agent: impl Into<EcoString>,
|
||||
cert: Certificate<'static>,
|
||||
) -> Self {
|
||||
Self {
|
||||
user_agent: user_agent.into(),
|
||||
cert_path: None,
|
||||
@ -96,7 +98,7 @@ impl Downloader {
|
||||
/// - Returns `None` if `--cert` and `TYPST_CERT` are not set.
|
||||
/// - Returns `Some(Ok(cert))` if the certificate was loaded successfully.
|
||||
/// - Returns `Some(Err(err))` if an error occurred while loading the certificate.
|
||||
pub fn cert(&self) -> Option<io::Result<&Certificate>> {
|
||||
pub fn cert(&self) -> Option<io::Result<&Certificate<'static>>> {
|
||||
self.cert_path.as_ref().map(|path| {
|
||||
self.cert.get_or_try_init(|| {
|
||||
let pem = std::fs::read(path)?;
|
||||
@ -107,31 +109,34 @@ impl Downloader {
|
||||
|
||||
/// Download binary data from the given url.
|
||||
#[allow(clippy::result_large_err)]
|
||||
pub fn download(&self, url: &str) -> Result<ureq::Response, ureq::Error> {
|
||||
let mut builder = ureq::AgentBuilder::new();
|
||||
let mut tls = TlsConnector::builder();
|
||||
pub fn download(
|
||||
&self,
|
||||
url: &str,
|
||||
) -> Result<ureq::http::Response<ureq::Body>, ureq::Error> {
|
||||
let mut builder = ureq::config::Config::builder();
|
||||
|
||||
// Set user agent.
|
||||
builder = builder.user_agent(&self.user_agent);
|
||||
|
||||
// Get the network proxy config from the environment and apply it.
|
||||
if let Some(proxy) = env_proxy::for_url_str(url)
|
||||
.to_url()
|
||||
.and_then(|url| ureq::Proxy::new(url).ok())
|
||||
{
|
||||
builder = builder.proxy(proxy);
|
||||
}
|
||||
|
||||
// Apply a custom CA certificate if present.
|
||||
if let Some(cert) = self.cert() {
|
||||
tls.add_root_certificate(cert?.clone());
|
||||
}
|
||||
let maybe_cert = self.cert().transpose()?.cloned().map_or(
|
||||
RootCerts::PlatformVerifier,
|
||||
|cert| {
|
||||
let certs = vec![cert];
|
||||
RootCerts::Specific(Arc::new(certs))
|
||||
},
|
||||
);
|
||||
|
||||
// Configure native TLS.
|
||||
let connector = tls.build().map_err(io::Error::other)?;
|
||||
builder = builder.tls_connector(Arc::new(connector));
|
||||
let tls_config = ureq::tls::TlsConfig::builder()
|
||||
.provider(TlsProvider::NativeTls)
|
||||
.root_certs(maybe_cert);
|
||||
|
||||
builder.build().get(url).call()
|
||||
builder = builder.tls_config(tls_config.build());
|
||||
|
||||
let agent = ureq::Agent::new_with_config(builder.build());
|
||||
|
||||
agent.get(url).call()
|
||||
}
|
||||
|
||||
/// Download binary data from the given url and report its progress.
|
||||
@ -170,7 +175,7 @@ const SAMPLES: usize = 5;
|
||||
/// over a websocket and reports its progress.
|
||||
struct RemoteReader<'p> {
|
||||
/// The reader returned by the ureq::Response.
|
||||
reader: Box<dyn Read + Send + Sync + 'static>,
|
||||
reader: ureq::BodyReader<'static>,
|
||||
/// The download state, holding download metadata for progress reporting.
|
||||
state: DownloadState,
|
||||
/// The instant at which progress was last reported.
|
||||
@ -184,13 +189,18 @@ impl<'p> RemoteReader<'p> {
|
||||
///
|
||||
/// The 'Content-Length' header is used as a size hint for read
|
||||
/// optimization, if present.
|
||||
fn from_response(response: Response, progress: &'p mut dyn Progress) -> Self {
|
||||
fn from_response(
|
||||
response: ureq::http::Response<ureq::Body>,
|
||||
progress: &'p mut dyn Progress,
|
||||
) -> Self {
|
||||
let content_len: Option<usize> = response
|
||||
.header("Content-Length")
|
||||
.headers()
|
||||
.get("Content-Length")
|
||||
.and_then(|header| header.to_str().ok())
|
||||
.and_then(|header| header.parse().ok());
|
||||
|
||||
Self {
|
||||
reader: response.into_reader(),
|
||||
reader: response.into_body().into_reader(),
|
||||
last_progress: None,
|
||||
state: DownloadState {
|
||||
content_len,
|
||||
|
@ -150,10 +150,10 @@ impl PackageStorage {
|
||||
.get_or_try_init(|| {
|
||||
let url = format!("{DEFAULT_REGISTRY}/{DEFAULT_NAMESPACE}/index.json");
|
||||
match self.downloader.download(&url) {
|
||||
Ok(response) => response.into_json().map_err(|err| {
|
||||
Ok(mut response) => response.body_mut().read_json().map_err(|err| {
|
||||
eco_format!("failed to parse package index: {err}")
|
||||
}),
|
||||
Err(ureq::Error::Status(404, _)) => {
|
||||
Err(ureq::Error::StatusCode(404)) => {
|
||||
bail!("failed to fetch package index (not found)")
|
||||
}
|
||||
Err(err) => bail!("failed to fetch package index ({err})"),
|
||||
@ -181,7 +181,7 @@ impl PackageStorage {
|
||||
|
||||
let data = match self.downloader.download_with_progress(&url, progress) {
|
||||
Ok(data) => data,
|
||||
Err(ureq::Error::Status(404, _)) => {
|
||||
Err(ureq::Error::StatusCode(404)) => {
|
||||
if let Ok(version) = self.determine_latest_version(&spec.versionless()) {
|
||||
return Err(PackageError::VersionNotFound(spec.clone(), version));
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user