mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Use scheme parsing to determine absolute vs. relative URLs (#2904)
## Summary
We have a heuristic in `File` that attempts to detect whether a URL is
absolute or relative. However, `contains("://")` is prone to false
positive. In the linked issues, the URLs look like:
```
/packages/5a/d8/4d75d1e4287ad9d051aab793c68f902c9c55c4397636b5ee540ebd15aedf/pytz-2005k.tar.bz2?hash=597b596dc1c2c130cd0a57a043459c3bd6477c640c07ac34ca3ce8eed7e6f30c&remote=4d75d1e428/pytz-2005k.tar.bz2 (sha256)
=597b596dc1c2c130cd0a57a043459c3bd6477c640c07ac34ca3ce8eed7e6f30c
```
Which is relative, but includes `://`.
Instead, we should determine whether the URL has a _scheme_ which
matches the `Url` crate internally.
Closes https://github.com/astral-sh/uv/issues/2899.
This commit is contained in:
parent
bdeab55193
commit
cc3c5700e1
2 changed files with 19 additions and 34 deletions
|
@ -1,37 +1,19 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
/// Join a possibly relative URL to a base URL.
|
||||
///
|
||||
/// When `maybe_relative` is not relative, then it is parsed and returned with
|
||||
/// `base` being ignored.
|
||||
///
|
||||
/// This is useful for parsing URLs that may be absolute or relative, with a
|
||||
/// known base URL, and that doesn't require having already parsed a `BaseUrl`.
|
||||
pub fn base_url_join_relative(base: &str, maybe_relative: &str) -> Result<Url, JoinRelativeError> {
|
||||
match Url::parse(maybe_relative) {
|
||||
Ok(absolute) => Ok(absolute),
|
||||
Err(err) => {
|
||||
if err == url::ParseError::RelativeUrlWithoutBase {
|
||||
let base_url = Url::parse(base).map_err(|err| JoinRelativeError::ParseError {
|
||||
original: base.to_string(),
|
||||
source: err,
|
||||
})?;
|
||||
/// Join a relative URL to a base URL.
|
||||
pub fn base_url_join_relative(base: &str, relative: &str) -> Result<Url, JoinRelativeError> {
|
||||
let base_url = Url::parse(base).map_err(|err| JoinRelativeError::ParseError {
|
||||
original: base.to_string(),
|
||||
source: err,
|
||||
})?;
|
||||
|
||||
base_url
|
||||
.join(maybe_relative)
|
||||
.map_err(|_| JoinRelativeError::ParseError {
|
||||
original: format!("{base}/{maybe_relative}"),
|
||||
source: err,
|
||||
})
|
||||
} else {
|
||||
Err(JoinRelativeError::ParseError {
|
||||
original: maybe_relative.to_string(),
|
||||
source: err,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
base_url
|
||||
.join(relative)
|
||||
.map_err(|err| JoinRelativeError::ParseError {
|
||||
original: format!("{base}/{relative}"),
|
||||
source: err,
|
||||
})
|
||||
}
|
||||
|
||||
/// An error that occurs when `base_url_join_relative` fails.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue