diff --git a/config.toml b/config.toml index d3543a5..1ad060b 100644 --- a/config.toml +++ b/config.toml @@ -2,7 +2,7 @@ refresh_rate = "1s" [server] -address="127.0.0.1:8020" +address="0.0.0.0:8020" #url = "https://rustypaste.shuttleapp.rs" #workers=4 max_content_length = "10MB" @@ -10,6 +10,7 @@ upload_path = "./upload" timeout = "30s" expose_version = false style="monokai" +pretty_default = true landing_page = """ ┬─┐┬ ┬┌─┐┌┬┐┬ ┬┌─┐┌─┐┌─┐┌┬┐┌─┐ ├┬┘│ │└─┐ │ └┬┘├─┘├─┤└─┐ │ ├┤ diff --git a/src/config.rs b/src/config.rs index d0c12bf..e04a1af 100644 --- a/src/config.rs +++ b/src/config.rs @@ -48,6 +48,8 @@ pub struct ServerConfig { pub landing_page: Option, /// Expose version. pub expose_version: Option, + /// Default to pretty when Accept: allows it. + pub pretty_default: Option, /// Highlight.js style pub style: Option, } diff --git a/src/lib.rs b/src/lib.rs index b34766f..8bced2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,9 @@ pub mod random; /// Server routes. pub mod server; +/// Pretty renderer. +pub mod pretty; + /// HTTP headers. pub mod header; diff --git a/src/pretty.rs b/src/pretty.rs new file mode 100644 index 0000000..6ba5bf0 --- /dev/null +++ b/src/pretty.rs @@ -0,0 +1,47 @@ +use crate::config::Config; +use actix_web::{web, HttpRequest, HttpResponse, Error, http::header}; +use mime::Mime; +use text_template::*; +use std::collections::HashMap; +use std::str; + +/// Render a pretty HttpResponse. +pub fn render_pretty( + file: web::Path, + mime_type: Mime, + config: &Config, +) -> Result { + let mut template_values = HashMap::new(); + let tmpl_bytes = str::from_utf8(include_bytes!("pretty.html")).unwrap(); + let tmpl = Template::from(tmpl_bytes); + template_values.insert("file", file.as_str()); + template_values.insert("style", match &config.server.style { + Some(style) => style.as_str(), + None => "default", + }); + let mime_str = mime_type.to_string(); + if let Some(overrides) = &config.paste.highlight_override { + template_values.insert("type", if overrides.contains_key(&mime_str) { overrides[&mime_str].as_str() } else { "" }); + } + let rendered = tmpl.fill_in(&template_values); + + Ok(HttpResponse::Ok().content_type(mime::TEXT_HTML).body(rendered.to_string())) +} + +/// Check whether the request wants pretty mode. +pub fn want_pretty( + request: &HttpRequest, + by_default: bool, +) -> bool { + if request.query_string() == "nopretty" { + return false; + } + + let mut accepts_html = false; + + if let Some(accept) = request.headers().get(header::ACCEPT) { + accepts_html = accept.to_str().unwrap_or_default().find("text/html").is_some(); + } + + request.query_string() == "pretty" || (by_default && accepts_html) +} diff --git a/src/server.rs b/src/server.rs index fb5d329..70e69e8 100644 --- a/src/server.rs +++ b/src/server.rs @@ -4,9 +4,9 @@ use crate::file::Directory; use crate::header::{self, ContentDisposition}; use crate::mime as mime_util; use crate::paste::{Paste, PasteType}; +use crate::pretty; use crate::util; use crate::AUTH_TOKEN_ENV; -use text_template::*; use actix_files::NamedFile; use actix_multipart::Multipart; use actix_web::{error, get, post, web, Error, HttpRequest, HttpResponse}; @@ -19,7 +19,6 @@ use std::env; use std::fs; use std::str; use std::sync::RwLock; -use std::collections::HashMap; /// Shows the landing page. #[get("/")] @@ -85,21 +84,8 @@ async fn serve( .map_err(error::ErrorInternalServerError)? }; - if request.query_string() == "pretty" { - let mut values = HashMap::new(); - let tmpl_bytes = str::from_utf8(include_bytes!("pretty.html")).unwrap(); - let tmpl = Template::from(tmpl_bytes); - values.insert("file", file.as_str()); - values.insert("style", match &config.server.style { - Some(style) => style.as_str(), - None => "default", - }); - let mime_str = mime_type.to_string(); - if let Some(overrides) = &config.paste.highlight_override { - values.insert("type", if overrides.contains_key(&mime_str) { overrides[&mime_str].as_str() } else { "" }); - } - let rendered = tmpl.fill_in(&values); - return Ok(HttpResponse::Ok().content_type(mime::TEXT_HTML).body(rendered.to_string())) + if pretty::want_pretty(&request, config.server.pretty_default.unwrap_or(false)) { + return pretty::render_pretty(file, mime_type, &config) } let response = NamedFile::open(&path)?