Ignore query parameters in AssetPaths when determining the extension (#12828)

# Objective

A help thread on discord asked how to use signed URLs for assets. This
currently fails because the query parameters are included in the
extension, which causes no suitable loader to be found:

```
Failed to load asset 'http://localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject' with asset loader 'bevy_render::texture::image_loader::ImageLoader': 
Could not load texture file: Error reading image file localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject: invalid image extension: jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject, this is an error in `bevy_render`.
```

## Solution

Make `get_full_extension` remove everything after the first `?`
character.

If this is accepted then it should also be documented in `AssetPath`
that extensions cannot include question marks.

An alternative is to special case this handling only for wasm, but that
would be annoying for the
[bevy_web_asset](https://github.com/johanhelsing/bevy_web_asset) plugin,
and in my opinion also just more confusing overall.
This commit is contained in:
Kristoffer Søholm 2024-04-03 20:57:03 +02:00 committed by GitHub
parent 6ccb2a306e
commit 3928d01841
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -448,10 +448,19 @@ impl<'a> AssetPath<'a> {
/// Returns the full extension (including multiple '.' values).
/// Ex: Returns `"config.ron"` for `"my_asset.config.ron"`
///
/// Also strips out anything following a `?` to handle query parameters in URIs
pub fn get_full_extension(&self) -> Option<String> {
let file_name = self.path().file_name()?.to_str()?;
let index = file_name.find('.')?;
let extension = file_name[index + 1..].to_lowercase();
let mut extension = file_name[index + 1..].to_lowercase();
// Strip off any query parameters
let query = extension.find('?');
if let Some(offset) = query {
extension.truncate(offset);
}
Some(extension)
}
@ -930,5 +939,8 @@ mod tests {
let result = AssetPath::from("http://a#Foo");
assert_eq!(result.get_full_extension(), None);
let result = AssetPath::from("http://a.tar.bz2?foo=bar#Baz");
assert_eq!(result.get_full_extension(), Some("tar.bz2".to_string()));
}
}