Use web::block in post_comment

main
Elnu 2 years ago
parent bf7efec848
commit 1de25aaca9

@ -19,12 +19,22 @@ struct AppState {
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 {
BadOrigin,
AccessError,
DatabaseError,
}
enum CommentCreationError {
DatabaseAccessError(DatabaseAccessError),
BadParent,
}
impl DatabaseAccessError {
fn to_http_response(&self) -> HttpResponse {
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 {
fn get_db<'a>(
&'a self,
@ -183,13 +202,8 @@ async fn post_comment(
if comment.email.is_none() && data.arguments.email_required {
return HttpResponse::BadRequest().reason("email required").finish();
}
let origin = match request.head().headers().get("Origin") {
Some(origin) => match origin.to_str() {
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
let origin = match get_request_origin(&request) {
Some(origin) => origin,
None => return HttpResponse::BadRequest().reason("bad origin").finish(),
};
// 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
'outer: loop {
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;
}
}
@ -223,9 +237,10 @@ async fn post_comment(
.finish()
}
};
let database = match data.get_db(&request) {
match web::block(move || {
let database = match data.get_db_with_origin(Some(origin)) {
Ok(database) => database,
Err(err) => return err.to_http_response(),
Err(err) => return Err(CommentCreationError::DatabaseAccessError(err)),
};
if let Some(parent) = comment.parent {
'outer2: loop {
@ -240,23 +255,22 @@ async fn post_comment(
}
}
}
Err(_) => {
return HttpResponse::InternalServerError()
.reason("failed to get comments")
.finish()
}
}
return HttpResponse::BadRequest()
.reason("invalid comment parent")
.finish();
Err(_) => return Err(CommentCreationError::DatabaseAccessError(DatabaseAccessError::DatabaseError)),
};
return Err(CommentCreationError::BadParent);
}
}
if let Err(_) = database.create_comment(&comment) {
return HttpResponse::InternalServerError()
.reason("failed to create comment")
.finish();
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(),
}
HttpResponse::Ok().into()
}
Err(_) => HttpResponse::BadRequest()
.reason("failed to parse request body")

Loading…
Cancel
Save