Merge pull request #1 from NoraCodes/nora/redirect_on_invalid_utf8
Redirect on invalid UTF-8 in /p/
This commit is contained in:
31
src/models/maybe_redirect.rs
Normal file
31
src/models/maybe_redirect.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
use rocket::{
|
||||||
|
request::Request,
|
||||||
|
response::{Redirect, Responder, Result},
|
||||||
|
};
|
||||||
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
|
pub enum MaybeRedirect {
|
||||||
|
Redirect(Box<Redirect>),
|
||||||
|
Template(Box<Template>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Redirect> for MaybeRedirect {
|
||||||
|
fn from(other: Redirect) -> Self {
|
||||||
|
Self::Redirect(Box::new(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Template> for MaybeRedirect {
|
||||||
|
fn from(other: Template) -> Self {
|
||||||
|
Self::Template(Box::new(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 'o: 'r> Responder<'r, 'o> for MaybeRedirect {
|
||||||
|
fn respond_to(self, req: &'r Request<'_>) -> Result<'o> {
|
||||||
|
match self {
|
||||||
|
Self::Template(t) => t.respond_to(req),
|
||||||
|
Self::Redirect(r) => r.respond_to(req),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pub mod maybe_redirect;
|
||||||
pub mod paste_id;
|
pub mod paste_id;
|
||||||
pub mod pretty;
|
pub mod pretty;
|
||||||
pub mod pretty_syntax;
|
pub mod pretty_syntax;
|
||||||
|
|||||||
@@ -10,16 +10,16 @@ static SYNTAXES: &[u8] =
|
|||||||
static THEMES: &[u8] =
|
static THEMES: &[u8] =
|
||||||
include_bytes!("../../resources/themes/ayu_dark.tmTheme");
|
include_bytes!("../../resources/themes/ayu_dark.tmTheme");
|
||||||
|
|
||||||
pub fn get_pretty_body(path: &Path, ext: &str) -> String {
|
pub fn get_pretty_body(path: &Path, ext: &str) -> std::io::Result<String> {
|
||||||
let ss: SyntaxSet = syntect::dumps::from_binary(SYNTAXES);
|
let ss: SyntaxSet = syntect::dumps::from_binary(SYNTAXES);
|
||||||
|
|
||||||
let mut theme_cursor = std::io::Cursor::new(THEMES);
|
let mut theme_cursor = std::io::Cursor::new(THEMES);
|
||||||
let theme = ThemeSet::load_from_reader(&mut theme_cursor).unwrap();
|
let theme = ThemeSet::load_from_reader(&mut theme_cursor).unwrap();
|
||||||
|
|
||||||
let content = fs::read_to_string(path).unwrap();
|
let content = fs::read_to_string(path)?;
|
||||||
let syntax = ss
|
let syntax = ss
|
||||||
.find_syntax_by_token(ext)
|
.find_syntax_by_token(ext)
|
||||||
.unwrap_or_else(|| ss.find_syntax_plain_text());
|
.unwrap_or_else(|| ss.find_syntax_plain_text());
|
||||||
|
|
||||||
highlighted_html_for_string(&content, &ss, syntax, &theme)
|
Ok(highlighted_html_for_string(&content, &ss, syntax, &theme))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
|
use rocket::response::Redirect;
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::io::ErrorKind::InvalidData;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::get_upload_dir;
|
use crate::get_upload_dir;
|
||||||
|
use crate::models::maybe_redirect::MaybeRedirect;
|
||||||
use crate::models::paste_id::PasteId;
|
use crate::models::paste_id::PasteId;
|
||||||
use crate::models::pretty::get_pretty_body;
|
use crate::models::pretty::get_pretty_body;
|
||||||
|
|
||||||
#[get("/p/<id>", rank = 2)]
|
#[get("/p/<id>", rank = 2)]
|
||||||
pub async fn pretty_retrieve(id: PasteId<'_>) -> Option<Template> {
|
pub async fn pretty_retrieve(id: PasteId<'_>) -> Option<MaybeRedirect> {
|
||||||
let filepath = Path::new(&get_upload_dir()).join(format!("{id}", id = id));
|
let filepath = Path::new(&get_upload_dir()).join(format!("{id}", id = id));
|
||||||
|
|
||||||
let contents = get_pretty_body(&filepath, &String::from("txt"));
|
let contents = match get_pretty_body(&filepath, &String::from("txt")) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) if e.kind() == InvalidData => {
|
||||||
|
return Some(Redirect::to(format!("/{}", id)).into());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert("title", id.to_string());
|
map.insert("title", id.to_string());
|
||||||
@@ -19,7 +30,7 @@ pub async fn pretty_retrieve(id: PasteId<'_>) -> Option<Template> {
|
|||||||
let rendered = Template::render("pretty.html", &map);
|
let rendered = Template::render("pretty.html", &map);
|
||||||
|
|
||||||
match tree_magic::match_filepath("text/plain", &filepath) {
|
match tree_magic::match_filepath("text/plain", &filepath) {
|
||||||
true => Some(rendered),
|
true => Some(rendered.into()),
|
||||||
false => None,
|
false => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
|
use rocket::response::Redirect;
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::io::ErrorKind::InvalidData;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::get_upload_dir;
|
use crate::get_upload_dir;
|
||||||
|
use crate::models::maybe_redirect::MaybeRedirect;
|
||||||
use crate::models::pretty::get_pretty_body;
|
use crate::models::pretty::get_pretty_body;
|
||||||
use crate::models::pretty_syntax::PasteIdSyntax;
|
use crate::models::pretty_syntax::PasteIdSyntax;
|
||||||
|
|
||||||
#[get("/p/<id_ext>", rank = 1)]
|
#[get("/p/<id_ext>", rank = 1)]
|
||||||
pub async fn pretty_retrieve_ext(
|
pub async fn pretty_retrieve_ext(
|
||||||
id_ext: PasteIdSyntax<'_>,
|
id_ext: PasteIdSyntax<'_>,
|
||||||
) -> Option<Template> {
|
) -> Option<MaybeRedirect> {
|
||||||
let id = id_ext.get_fname();
|
let id = id_ext.get_fname();
|
||||||
let ext = id_ext.get_ext();
|
let ext = id_ext.get_ext();
|
||||||
|
|
||||||
let filepath = Path::new(&get_upload_dir()).join(id.to_string());
|
let filepath = Path::new(&get_upload_dir()).join(id.to_string());
|
||||||
|
|
||||||
let contents = get_pretty_body(&filepath, &ext.to_string());
|
let contents = match get_pretty_body(&filepath, &ext.to_string()) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) if e.kind() == InvalidData => {
|
||||||
|
return Some(Redirect::to(format!("/{}", id)).into());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
map.insert("title", id.to_string());
|
map.insert("title", id.to_string());
|
||||||
@@ -24,7 +35,7 @@ pub async fn pretty_retrieve_ext(
|
|||||||
let rendered = Template::render("pretty.html", &map);
|
let rendered = Template::render("pretty.html", &map);
|
||||||
|
|
||||||
match tree_magic::match_filepath("text/plain", &filepath) {
|
match tree_magic::match_filepath("text/plain", &filepath) {
|
||||||
true => Some(rendered),
|
true => Some(rendered.into()),
|
||||||
false => None,
|
false => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user