use crate::PublicKey;
use reqwest::{Method, RequestBuilder};
use super::resource::{IntoPubkyResource, IntoResourcePath, PubkyResource, ResourcePath};
use crate::{
PubkyHttpClient, PubkySession, cross_log,
errors::{RequestError, Result},
};
#[derive(Debug, Clone)]
pub struct SessionStorage {
pub(crate) client: PubkyHttpClient,
pub(crate) user: PublicKey,
#[cfg(not(target_arch = "wasm32"))]
pub(crate) cookie: String,
}
impl SessionStorage {
#[must_use]
pub fn new(session: &PubkySession) -> Self {
Self {
client: session.client.clone(),
user: session.info.public_key().clone(),
#[cfg(not(target_arch = "wasm32"))]
cookie: session.cookie.clone(),
}
}
#[must_use]
pub fn public(&self) -> PublicStorage {
PublicStorage {
client: self.client.clone(),
}
}
pub(crate) async fn request<P: IntoResourcePath>(
&self,
method: Method,
path: P,
) -> Result<RequestBuilder> {
let path: ResourcePath = path.into_abs_path()?;
let resource = PubkyResource::new(self.user.clone(), path.as_str())?;
let url = resource.to_transport_url()?;
cross_log!(debug, "Session storage {} request {}", method, url);
let rb = self.client.cross_request(method, url).await?;
#[cfg(not(target_arch = "wasm32"))]
let rb = self.with_session_cookie(rb);
Ok(rb)
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn with_session_cookie(&self, rb: RequestBuilder) -> RequestBuilder {
let cookie_name = self.user.z32();
rb.header(
reqwest::header::COOKIE,
format!("{cookie_name}={}", self.cookie),
)
}
}
#[derive(Debug, Clone)]
pub struct PublicStorage {
pub(crate) client: PubkyHttpClient,
}
impl PublicStorage {
pub fn new() -> Result<Self> {
Ok(Self {
client: PubkyHttpClient::new()?,
})
}
pub(crate) async fn request<A: IntoPubkyResource>(
&self,
method: Method,
addr: A,
) -> Result<RequestBuilder> {
let resource: PubkyResource = addr.into_pubky_resource()?;
let url = resource.to_transport_url()?;
cross_log!(debug, "Public storage {} request {}", method, url);
let rb = self.client.cross_request(method, url).await?;
Ok(rb)
}
}
#[inline]
pub fn dir_trailing_slash_error() -> RequestError {
RequestError::Validation {
message: "directory listings must end with `/`".into(),
}
}