Use web::block in post_comment

main
Elnu 2 years ago
parent bf7efec848
commit 1de25aaca9

@ -19,12 +19,22 @@ struct AppState {
arguments: Arguments, arguments: Arguments,
} }
// TODO: Make error handling system not bad.
// Currently, it's a horrible mix of custom error types a direct HttpResponses,
// due to not being able to pass HttpResponse out of web::block...
// Well, it works, at least.
enum DatabaseAccessError { enum DatabaseAccessError {
BadOrigin, BadOrigin,
AccessError, AccessError,
DatabaseError, DatabaseError,
} }
enum CommentCreationError {
DatabaseAccessError(DatabaseAccessError),
BadParent,
}
impl DatabaseAccessError { impl DatabaseAccessError {
fn to_http_response(&self) -> HttpResponse { fn to_http_response(&self) -> HttpResponse {
match self { match self {
@ -39,6 +49,15 @@ impl DatabaseAccessError {
} }
} }
impl CommentCreationError {
fn to_http_response(&self) -> HttpResponse {
match self {
Self::DatabaseAccessError(error) => error.to_http_response(),
Self::BadParent => HttpResponse::BadRequest().reason("invalid comment parent").finish(),
}
}
}
impl AppState { impl AppState {
fn get_db<'a>( fn get_db<'a>(
&'a self, &'a self,
@ -183,13 +202,8 @@ async fn post_comment(
if comment.email.is_none() && data.arguments.email_required { if comment.email.is_none() && data.arguments.email_required {
return HttpResponse::BadRequest().reason("email required").finish(); return HttpResponse::BadRequest().reason("email required").finish();
} }
let origin = match request.head().headers().get("Origin") { let origin = match get_request_origin(&request) {
Some(origin) => match origin.to_str() { Some(origin) => origin,
Ok(origin) => origin,
// If the Origin is not valid ASCII, it is a bad request not sent from a browser
Err(_) => return HttpResponse::BadRequest().reason("bad origin").finish(),
},
// If there is no Origin header, it is a bad request not sent from a browser
None => return HttpResponse::BadRequest().reason("bad origin").finish(), None => return HttpResponse::BadRequest().reason("bad origin").finish(),
}; };
// Check to see if provided URL is in scope. // Check to see if provided URL is in scope.
@ -198,7 +212,7 @@ async fn post_comment(
// https://github.com/rust-lang/rust/issues/48594 // https://github.com/rust-lang/rust/issues/48594
'outer: loop { 'outer: loop {
for site_root in data.databases.keys() { for site_root in data.databases.keys() {
if site_root.starts_with(origin) && url.starts_with(site_root) { if site_root.starts_with(&origin) && url.starts_with(site_root) {
break 'outer; break 'outer;
} }
} }
@ -223,40 +237,40 @@ async fn post_comment(
.finish() .finish()
} }
}; };
let database = match data.get_db(&request) { match web::block(move || {
Ok(database) => database, let database = match data.get_db_with_origin(Some(origin)) {
Err(err) => return err.to_http_response(), Ok(database) => database,
}; Err(err) => return Err(CommentCreationError::DatabaseAccessError(err)),
if let Some(parent) = comment.parent { };
'outer2: loop { if let Some(parent) = comment.parent {
match database.get_comments(&comment.content_id) { 'outer2: loop {
Ok(comments) => { match database.get_comments(&comment.content_id) {
for other_comment in comments.iter() { Ok(comments) => {
if other_comment.id.unwrap() == parent { for other_comment in comments.iter() {
if other_comment.parent.is_none() { if other_comment.id.unwrap() == parent {
break 'outer2; if other_comment.parent.is_none() {
break 'outer2;
}
break;
} }
break;
} }
} }
} Err(_) => return Err(CommentCreationError::DatabaseAccessError(DatabaseAccessError::DatabaseError)),
Err(_) => { };
return HttpResponse::InternalServerError() return Err(CommentCreationError::BadParent);
.reason("failed to get comments")
.finish()
}
} }
return HttpResponse::BadRequest()
.reason("invalid comment parent")
.finish();
} }
if let Err(_) = database.create_comment(&comment) {
return Err(CommentCreationError::DatabaseAccessError(DatabaseAccessError::DatabaseError));
}
Ok(())
}).await {
Ok(result) => match result {
Ok(_) => HttpResponse::Ok().into(),
Err(error) => error.to_http_response(),
},
Err(_) => DatabaseAccessError::AccessError.to_http_response(),
} }
if let Err(_) = database.create_comment(&comment) {
return HttpResponse::InternalServerError()
.reason("failed to create comment")
.finish();
}
HttpResponse::Ok().into()
} }
Err(_) => HttpResponse::BadRequest() Err(_) => HttpResponse::BadRequest()
.reason("failed to parse request body") .reason("failed to parse request body")

Loading…
Cancel
Save