use serde_derive::Deserialize;
use std::borrow::Cow;
use std::sync::Arc;
use crate::components::{
Comment, Content, HTPage, MaybeFillInput, MaybeFillTextArea, PostItem, UserLink,
};
use crate::resp_types::{RespMinimalAuthorInfo, RespPostCommentInfo, RespPostListPost};
use crate::util::author_is_me;
use crate::PageBaseData;
mod communities;
mod posts;
mod r#static;
const COOKIE_AGE: u32 = 60 * 60 * 24 * 365;
#[derive(Deserialize)]
struct ReturnToParams<'a> {
return_to: Option<Cow<'a, str>>,
}
type CookieMap<'a> = std::collections::HashMap<&'a str, ginger::Cookie<'a>>;
fn get_cookie_map<'a>(src: Option<&'a str>) -> Result<CookieMap<'a>, ginger::ParseError> {
match src {
None => Ok(Default::default()),
Some(src) => {
use fallible_iterator::FallibleIterator;
fallible_iterator::convert(ginger::parse_cookies(src))
.map(|cookie| Ok((cookie.name, cookie)))
.collect()
}
}
}
fn get_cookie_map_for_req<'a>(
req: &'a hyper::Request<hyper::Body>,
) -> Result<CookieMap<'a>, crate::Error> {
get_cookie_map_for_headers(req.headers())
}
fn get_cookie_map_for_headers<'a>(
headers: &'a hyper::HeaderMap,
) -> Result<CookieMap<'a>, crate::Error> {
get_cookie_map(get_cookies_string(headers)?).map_err(Into::into)
}
fn get_cookies_string<'a>(headers: &'a hyper::HeaderMap) -> Result<Option<&'a str>, crate::Error> {
Ok(headers
.get(hyper::header::COOKIE)
.map(|x| x.to_str())
.transpose()?)
}
fn with_auth(
mut new_req: hyper::Request<hyper::Body>,
cookies: &CookieMap<'_>,
) -> Result<hyper::Request<hyper::Body>, hyper::header::InvalidHeaderValue> {
let token = cookies.get("hitideToken").map(|c| c.value);
if let Some(token) = token {
new_req.headers_mut().insert(
hyper::header::AUTHORIZATION,
hyper::header::HeaderValue::from_str(&format!("Bearer {}", token))?,
);
}
Ok(new_req)
}
async fn fetch_base_data(
backend_host: &str,
http_client: &crate::HttpClient,
cookies: &CookieMap<'_>,
) -> Result<PageBaseData, crate::Error> {
let login = {
let api_res = http_client
.request(with_auth(
hyper::Request::get(format!("{}/api/unstable/logins/~current", backend_host))
.body(Default::default())?,
&cookies,
)?)
.await?;
if api_res.status() == hyper::StatusCode::UNAUTHORIZED {
Ok(None)
} else {
let api_res = res_to_error(api_res).await?;
let api_res = hyper::body::to_bytes(api_res.into_body()).await?;
serde_json::from_slice(&api_res)
}
}?;
Ok(PageBaseData { login })
}
fn html_response(html: String) ->