[web] [WIP] Fix sending OGP tags

This commit is contained in:
Emi Simpson 2021-11-02 14:17:47 -04:00
parent 56dbe50d2f
commit 2cfe9fcb5f
Signed by: Emi
GPG key ID: A12F2C2FFDC3D847
3 changed files with 44 additions and 20 deletions

View file

@ -6,6 +6,13 @@ port: 1312
# The address the server should bind to
address: 0.0.0.0
# The base URL the server will be running under, with no trailing slash
#
# This is also your opportunity to serve requests under a subpath. For example, if you
# want pronouns.today to only run on the /pronouns route of your webserver, you can set
# this to https://example.com/pronouns
base_url: https://pronouns.today
# A list of pronouns recognized by the server
#
# WARNING: When adding pronouns, only add pronouns to the bottom of the list, and do not

View file

@ -82,6 +82,11 @@ pub struct Run {
/// for warnings when changing this value. formatted as a list of comma seperated
/// five-form pronouns, e.g. she/her/her/hers/herself,he/him/his/his/himself
pub pronouns: Option<PronounList>,
#[argh(option, long="base")]
/// the base url content is served under, starting with the protocol (https://) and without a
/// trailing slash
pub base_url: Option<String>,
}
impl Run {
@ -131,6 +136,9 @@ pub struct Conf {
/// The address to bind to. Defaults to 0.0.0.0
pub address: IpAddr,
/// The base url the server will be running under, with no trailing slash
pub base_url: String,
}
impl Conf {
@ -138,6 +146,7 @@ impl Conf {
self.port = args.port.unwrap_or(self.port);
self.address = args.address.unwrap_or(self.address);
self.instance_settings.pronoun_list = args.pronouns.map(Into::into).unwrap_or(self.instance_settings.pronoun_list);
self.base_url = args.base_url.unwrap_or(self.base_url);
self
}
}
@ -148,6 +157,7 @@ impl Default for Conf {
instance_settings: InstanceSettings::default(),
port: 1312,
address: IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
base_url: "https://pronouns.today".into(),
}
}
}

View file

@ -3,6 +3,7 @@ pub mod contrast;
pub mod statics;
pub mod configuration;
use crate::configuration::Conf;
use std::io::IoSlice;
use crate::statics::StaticAsset;
use smol::io::AsyncWriteExt;
@ -105,13 +106,13 @@ async fn start_server(config: configuration::Conf, executor: &smol::LocalExecuto
let connection = smol::net::TcpListener::bind(socket_addr).await?;
let mut incoming = connection.incoming();
// Make the instance settings immortal
let instance_settings = Box::leak(Box::new(config.instance_settings));
// Make the configuration immortal
let config = Box::leak(Box::new(config));
while let Some(stream) = incoming.next().await {
match stream {
Ok(stream) => {
executor.spawn(handle_request(stream, instance_settings)).detach();
executor.spawn(handle_request(stream, config)).detach();
},
Err(e) => {
log::error!("IO Error with client/server connection: {}", e);
@ -135,7 +136,7 @@ async fn start_server(config: configuration::Conf, executor: &smol::LocalExecuto
/// - Serialization of the response is done using [`Response::into_bytes()`]
async fn handle_request(
raw_stream: impl smol::io::AsyncRead + smol::io::AsyncWrite + Unpin,
settings: &InstanceSettings
conf: &Conf,
) {
let mut stream = smol::io::BufReader::new(raw_stream);
@ -153,7 +154,7 @@ async fn handle_request(
};
let response = route_request(&req)
.generate_response(settings);
.generate_response(conf);
let io_slices = response.into_io_slices();
for slice in io_slices {
@ -194,9 +195,10 @@ fn route_request(req: &ScgiRequest) -> Route {
_ => return Route::BadRequest(BadRequest::MethodNotAllowed),
}
let mut segments: Vec<_> = req.headers
let request_uri = req.headers
.get("REQUEST_URI")
.expect("Misconfigured server didn't send a REQUEST_URI header")
.expect("Misconfigured server didn't send a REQUEST_URI header");
let mut segments: Vec<_> = request_uri
.split("/")
.filter(|s| s.len() > 0)
.collect();
@ -241,13 +243,14 @@ fn route_request(req: &ScgiRequest) -> Route {
(None, Some(_)) => unreachable!(),
};
let response_type = if is_thumb {
Route::SendThumbnail
} else {
Route::SendPronounPage
};
let name = name.map(|n| (*n).to_owned());
response_type(name.map(|n| (*n).to_owned()), prefs)
if is_thumb {
Route::SendThumbnail(name, prefs)
} else {
let uri = request_uri.trim_end_matches('/').to_owned();
Route::SendPronounPage(name, prefs, uri)
}
}
/// Determines the type of route that the request should be met with, and necessary data
@ -276,8 +279,9 @@ enum Route {
/// Respond with an HTML pronoun page.
///
/// Takes the user's name (if specified), and the preferences of that user, or
/// [`None`] for defults
SendPronounPage(Option<String>, Option<UserPreferences>),
/// [`None`] for defults. The third string is the URI of the current page,
/// ending without a /
SendPronounPage(Option<String>, Option<UserPreferences>, String),
/// Respond with an image containing the user's pronouns
///
@ -312,11 +316,12 @@ enum BadRequest {
impl Route {
/// Actually perform the action that each route entails
fn generate_response(self, settings: &InstanceSettings) -> Response {
fn generate_response(self, conf: &Conf) -> Response {
let settings = &conf.instance_settings;
let result = match self {
Route::SendStatic(data) => Ok(data.generate_response()),
Route::SendPronounPage(name, prefs) =>
Route::send_pronoun_page(name, prefs, settings),
Route::SendPronounPage(name, prefs, url) =>
Route::send_pronoun_page(name, prefs, url, conf),
Route::SendThumbnail(name, prefs) =>
Route::send_thumbnail(name, prefs, settings),
Route::GenerateLink =>
@ -332,15 +337,17 @@ impl Route {
fn send_pronoun_page(
name: Option<String>,
prefs: Option<UserPreferences>,
settings: &InstanceSettings,
uri: String,
conf: &Conf,
) -> Result<Response, BadRequest> {
let settings = &conf.instance_settings;
let pronoun = Route::get_pronoun(name.as_ref(), prefs, settings)?;
let body = IndexTemplate {
name,
pronoun,
pronouns: settings.pronoun_list.iter().enumerate().collect(),
url: String::new(), //TODO
url: format!("{}{}", &conf.base_url, uri), //TODO
}
.render()
.unwrap();