Better big form handling (#430)
* Allow customizing max form size from env vars * Add error page for unprocessable entities And change default http port to 7878 * Improve char counter: under the editor, more discrete, and give it a default value
This commit is contained in:
+17
-2
@@ -36,7 +36,10 @@ extern crate validator_derive;
|
||||
extern crate webfinger;
|
||||
|
||||
use diesel::r2d2::ConnectionManager;
|
||||
use rocket::State;
|
||||
use rocket::{
|
||||
Config, State,
|
||||
config::Limits
|
||||
};
|
||||
use rocket_csrf::CsrfFairingBuilder;
|
||||
use plume_models::{
|
||||
DATABASE_URL, Connection, Error,
|
||||
@@ -44,6 +47,7 @@ use plume_models::{
|
||||
search::{Searcher as UnmanagedSearcher, SearcherError},
|
||||
};
|
||||
use scheduled_thread_pool::ScheduledThreadPool;
|
||||
use std::env;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
@@ -95,7 +99,17 @@ Then try to restart Plume.
|
||||
exit(0);
|
||||
}).expect("Error setting Ctrl-c handler");
|
||||
|
||||
rocket::ignite()
|
||||
let mut config = Config::active().unwrap();
|
||||
config.set_address(env::var("ROCKET_ADDRESS").unwrap_or_else(|_| "localhost".to_owned())).unwrap();
|
||||
config.set_port(env::var("ROCKET_PORT").ok().map(|s| s.parse::<u16>().unwrap()).unwrap_or(7878));
|
||||
let _ = env::var("ROCKET_SECRET_KEY").map(|k| config.set_secret_key(k).unwrap());
|
||||
let form_size = &env::var("FORM_SIZE").unwrap_or_else(|_| "32".to_owned()).parse::<u64>().unwrap();
|
||||
let activity_size = &env::var("ACTIVITY_SIZE").unwrap_or_else(|_| "1024".to_owned()).parse::<u64>().unwrap();
|
||||
config.set_limits(Limits::new()
|
||||
.limit("forms", form_size * 1024)
|
||||
.limit("json", activity_size * 1024));
|
||||
|
||||
rocket::custom(config)
|
||||
.mount("/", routes![
|
||||
routes::blogs::details,
|
||||
routes::blogs::activity_details,
|
||||
@@ -196,6 +210,7 @@ Then try to restart Plume.
|
||||
])
|
||||
.register(catchers![
|
||||
routes::errors::not_found,
|
||||
routes::errors::unprocessable_entity,
|
||||
routes::errors::server_error
|
||||
])
|
||||
.manage(dbpool)
|
||||
|
||||
@@ -47,6 +47,16 @@ pub fn not_found(req: &Request) -> Ructe {
|
||||
))
|
||||
}
|
||||
|
||||
#[catch(422)]
|
||||
pub fn unprocessable_entity(req: &Request) -> Ructe {
|
||||
let conn = req.guard::<DbConn>().succeeded();
|
||||
let intl = req.guard::<I18n>().succeeded();
|
||||
let user = User::from_request(req).succeeded();
|
||||
render!(errors::unprocessable_entity(
|
||||
&(&*conn.unwrap(), &intl.unwrap().catalog, user)
|
||||
))
|
||||
}
|
||||
|
||||
#[catch(500)]
|
||||
pub fn server_error(req: &Request) -> Ructe {
|
||||
let conn = req.guard::<DbConn>().succeeded();
|
||||
|
||||
+17
-2
@@ -1,7 +1,8 @@
|
||||
use atom_syndication::{ContentBuilder, Entry, EntryBuilder, LinkBuilder, Person, PersonBuilder};
|
||||
use rocket::{
|
||||
http::{RawStr, uri::{FromUriParam, Query}},
|
||||
request::FromFormValue,
|
||||
http::{RawStr, Status, uri::{FromUriParam, Query}},
|
||||
Outcome,
|
||||
request::{self, FromFormValue, FromRequest, Request},
|
||||
response::NamedFile,
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -46,6 +47,20 @@ impl Page {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ContentLen(pub u64);
|
||||
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for ContentLen {
|
||||
type Error = ();
|
||||
|
||||
fn from_request(r: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
||||
match r.limits().get("forms") {
|
||||
Some(l) => Outcome::Success(ContentLen(l)),
|
||||
None => Outcome::Failure((Status::InternalServerError, ())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Default for Page {
|
||||
fn default() -> Self {
|
||||
Page(1)
|
||||
|
||||
+13
-9
@@ -24,7 +24,7 @@ use plume_models::{
|
||||
tags::*,
|
||||
users::User
|
||||
};
|
||||
use routes::{errors::ErrorPage, comments::NewCommentForm};
|
||||
use routes::{errors::ErrorPage, comments::NewCommentForm, ContentLen};
|
||||
use template_utils::Ructe;
|
||||
use Worker;
|
||||
use Searcher;
|
||||
@@ -103,7 +103,7 @@ pub fn new_auth(blog: String, i18n: I18n) -> Flash<Redirect> {
|
||||
}
|
||||
|
||||
#[get("/~/<blog>/new", rank = 1)]
|
||||
pub fn new(blog: String, user: User, conn: DbConn, intl: I18n) -> Result<Ructe, ErrorPage> {
|
||||
pub fn new(blog: String, user: User, cl: ContentLen, conn: DbConn, intl: I18n) -> Result<Ructe, ErrorPage> {
|
||||
let b = Blog::find_by_fqn(&*conn, &blog)?;
|
||||
|
||||
if !user.is_author_in(&*conn, &b)? {
|
||||
@@ -125,13 +125,14 @@ pub fn new(blog: String, user: User, conn: DbConn, intl: I18n) -> Result<Ructe,
|
||||
true,
|
||||
None,
|
||||
ValidationErrors::default(),
|
||||
medias
|
||||
medias,
|
||||
cl.0
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/~/<blog>/<slug>/edit")]
|
||||
pub fn edit(blog: String, slug: String, user: User, conn: DbConn, intl: I18n) -> Result<Ructe, ErrorPage> {
|
||||
pub fn edit(blog: String, slug: String, user: User, cl: ContentLen, conn: DbConn, intl: I18n) -> Result<Ructe, ErrorPage> {
|
||||
let b = Blog::find_by_fqn(&*conn, &blog)?;
|
||||
let post = Post::find_by_slug(&*conn, &slug, b.id)?;
|
||||
|
||||
@@ -168,13 +169,14 @@ pub fn edit(blog: String, slug: String, user: User, conn: DbConn, intl: I18n) ->
|
||||
!post.published,
|
||||
Some(post),
|
||||
ValidationErrors::default(),
|
||||
medias
|
||||
medias,
|
||||
cl.0
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/~/<blog>/<slug>/edit", data = "<form>")]
|
||||
pub fn update(blog: String, slug: String, user: User, conn: DbConn, form: LenientForm<NewPostForm>, worker: Worker, intl: I18n, searcher: Searcher)
|
||||
pub fn update(blog: String, slug: String, user: User, cl: ContentLen, form: LenientForm<NewPostForm>, worker: Worker, conn: DbConn, intl: I18n, searcher: Searcher)
|
||||
-> Result<Redirect, Ructe> {
|
||||
let b = Blog::find_by_fqn(&*conn, &blog).expect("post::update: blog error");
|
||||
let mut post = Post::find_by_slug(&*conn, &slug, b.id).expect("post::update: find by slug error");
|
||||
@@ -261,7 +263,8 @@ pub fn update(blog: String, slug: String, user: User, conn: DbConn, form: Lenien
|
||||
form.draft.clone(),
|
||||
Some(post),
|
||||
errors.clone(),
|
||||
medias.clone()
|
||||
medias.clone(),
|
||||
cl.0
|
||||
)))
|
||||
}
|
||||
}
|
||||
@@ -290,7 +293,7 @@ pub fn valid_slug(title: &str) -> Result<(), ValidationError> {
|
||||
}
|
||||
|
||||
#[post("/~/<blog_name>/new", data = "<form>")]
|
||||
pub fn create(blog_name: String, form: LenientForm<NewPostForm>, user: User, conn: DbConn, worker: Worker, intl: I18n, searcher: Searcher) -> Result<Redirect, Result<Ructe, ErrorPage>> {
|
||||
pub fn create(blog_name: String, form: LenientForm<NewPostForm>, user: User, cl: ContentLen, conn: DbConn, worker: Worker, intl: I18n, searcher: Searcher) -> Result<Redirect, Result<Ructe, ErrorPage>> {
|
||||
let blog = Blog::find_by_fqn(&*conn, &blog_name).expect("post::create: blog error");;
|
||||
let slug = form.title.to_string().to_kebab_case();
|
||||
|
||||
@@ -384,7 +387,8 @@ pub fn create(blog_name: String, form: LenientForm<NewPostForm>, user: User, con
|
||||
form.draft,
|
||||
None,
|
||||
errors.clone(),
|
||||
medias
|
||||
medias,
|
||||
cl.0
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user