Support fetches with redirect (#76)
* Support fetches with redirect * pub
This commit is contained in:
parent
a5102d0633
commit
ec12fb3830
4 changed files with 25 additions and 10 deletions
|
@ -40,9 +40,10 @@ where
|
||||||
where
|
where
|
||||||
<Kind as Collection>::Error: From<Error>,
|
<Kind as Collection>::Error: From<Error>,
|
||||||
{
|
{
|
||||||
let json = fetch_object_http(&self.0, data).await?;
|
let res = fetch_object_http(&self.0, data).await?;
|
||||||
Kind::verify(&json, &self.0, data).await?;
|
let redirect_url = &res.url;
|
||||||
Kind::from_json(json, owner, data).await
|
Kind::verify(&res.object, redirect_url, data).await?;
|
||||||
|
Kind::from_json(res.object, owner, data).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,14 @@ pub mod object_id;
|
||||||
/// Resolves identifiers of the form `name@example.com`
|
/// Resolves identifiers of the form `name@example.com`
|
||||||
pub mod webfinger;
|
pub mod webfinger;
|
||||||
|
|
||||||
|
/// Response from fetching a remote object
|
||||||
|
pub struct FetchObjectResponse<Kind> {
|
||||||
|
/// The resolved object
|
||||||
|
pub object: Kind,
|
||||||
|
/// Contains the final URL (different from request URL in case of redirect)
|
||||||
|
pub url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
/// Fetch a remote object over HTTP and convert to `Kind`.
|
/// Fetch a remote object over HTTP and convert to `Kind`.
|
||||||
///
|
///
|
||||||
/// [crate::fetch::object_id::ObjectId::dereference] wraps this function to add caching and
|
/// [crate::fetch::object_id::ObjectId::dereference] wraps this function to add caching and
|
||||||
|
@ -38,7 +46,7 @@ pub mod webfinger;
|
||||||
pub async fn fetch_object_http<T: Clone, Kind: DeserializeOwned>(
|
pub async fn fetch_object_http<T: Clone, Kind: DeserializeOwned>(
|
||||||
url: &Url,
|
url: &Url,
|
||||||
data: &Data<T>,
|
data: &Data<T>,
|
||||||
) -> Result<Kind, Error> {
|
) -> Result<FetchObjectResponse<Kind>, Error> {
|
||||||
fetch_object_http_with_accept(url, data, FEDERATION_CONTENT_TYPE).await
|
fetch_object_http_with_accept(url, data, FEDERATION_CONTENT_TYPE).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +56,7 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
|
||||||
url: &Url,
|
url: &Url,
|
||||||
data: &Data<T>,
|
data: &Data<T>,
|
||||||
content_type: &str,
|
content_type: &str,
|
||||||
) -> Result<Kind, Error> {
|
) -> Result<FetchObjectResponse<Kind>, Error> {
|
||||||
let config = &data.config;
|
let config = &data.config;
|
||||||
// dont fetch local objects this way
|
// dont fetch local objects this way
|
||||||
debug_assert!(url.domain() != Some(&config.domain));
|
debug_assert!(url.domain() != Some(&config.domain));
|
||||||
|
@ -84,5 +92,9 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
|
||||||
return Err(Error::ObjectDeleted);
|
return Err(Error::ObjectDeleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json_limited().await
|
let url = res.url().clone();
|
||||||
|
Ok(FetchObjectResponse {
|
||||||
|
object: res.json_limited().await?,
|
||||||
|
url,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,10 +156,11 @@ where
|
||||||
return Err(anyhow!("Fetched remote object {} which was deleted", self).into());
|
return Err(anyhow!("Fetched remote object {} which was deleted", self).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let res2 = res?;
|
let res = res?;
|
||||||
|
let redirect_url = &res.url;
|
||||||
|
|
||||||
Kind::verify(&res2, self.inner(), data).await?;
|
Kind::verify(&res.object, redirect_url, data).await?;
|
||||||
Kind::from_json(res2, data).await
|
Kind::from_json(res.object, data).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ where
|
||||||
|
|
||||||
let res: Webfinger =
|
let res: Webfinger =
|
||||||
fetch_object_http_with_accept(&Url::parse(&fetch_url)?, data, "application/jrd+json")
|
fetch_object_http_with_accept(&Url::parse(&fetch_url)?, data, "application/jrd+json")
|
||||||
.await?;
|
.await?
|
||||||
|
.object;
|
||||||
|
|
||||||
debug_assert_eq!(res.subject, format!("acct:{identifier}"));
|
debug_assert_eq!(res.subject, format!("acct:{identifier}"));
|
||||||
let links: Vec<Url> = res
|
let links: Vec<Url> = res
|
||||||
|
|
Loading…
Add table
Reference in a new issue