diff options
-rw-r--r-- | src/main.rs | 95 |
1 files changed, 50 insertions, 45 deletions
diff --git a/src/main.rs b/src/main.rs index f1f9caa..8f756ef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -312,6 +312,7 @@ async fn build_response<C: Controller>( .ok_or_else(|| Error::BadRequest("Host header required".into()))? .to_str() .unwrap(); + if host != origin.host() { // We enforce an exact Host header to prevent DNS rebinding attacks. return Err(Error::BadRequest(format!("<h1>Bad Request: Unknown Host header</h1>\ @@ -366,62 +367,66 @@ async fn build_response<C: Controller>( return post_routes::build_response(origin, ¶ms, controller, ctx, body, parts).await; } - let mut tree = ctx.branch_head()?.tree(); + let tree = ctx.branch_head()?.tree(); - if ctx.path.components().next().is_some() { - let entr = match tree.and_then(|t| t.get_path(ctx.path.as_ref())) { - Ok(entr) => entr, - Err(_) => { - if unsanitized_path.ends_with('/') { - return Err(Error::NotFound("directory not found".into())); - } + if ctx.path.components().next().is_none() { + return get_routes::view_tree(tree, controller, &ctx, parts); + } - if controller.may_write_path(&ctx, parts) { - if params.action == "edit" { - return Ok(forms::edit_text_form( - &forms::EditForm::default(), - None, - controller, - &ctx, - parts, + match tree.and_then(|t| t.get_path(ctx.path.as_ref())) { + Ok(entr) => match entr.kind().unwrap() { + ObjectType::Blob => { + if unsanitized_path.ends_with('/') { + return Ok(Builder::new() + .status(StatusCode::FOUND) + .header( + "location", + controller.build_url_path( + &ctx.branch, + unsanitized_path.trim_end_matches('/'), + ), ) + .body("redirecting".into()) + .unwrap() .into()); - } else if params.action == "upload" { - return Ok(forms::upload_form(false, controller, &ctx, parts).into()); - } else { - return Err(Error::NotFound( - "file not found, but <a href=?action=edit>you can write it</a> or <a href=?action=upload>upload it</a>".into(), - )); - } - } else { - return Err(Error::NotFound("file not found".into())); } + get_routes::get_blob(entr, params, controller, ctx, parts) } - }; - - if entr.kind().unwrap() == ObjectType::Blob { + ObjectType::Tree => { + if !unsanitized_path.ends_with('/') { + return Err(Error::MissingTrailingSlash(parts.uri.path().to_owned())); + } + get_routes::view_tree(ctx.repo.find_tree(entr.id()), controller, &ctx, parts) + } + _other => panic!("unexpected object type"), + }, + Err(_) => { if unsanitized_path.ends_with('/') { - return Ok(Builder::new() - .status(StatusCode::FOUND) - .header( - "location", - controller - .build_url_path(&ctx.branch, unsanitized_path.trim_end_matches('/')), - ) - .body("redirecting".into()) - .unwrap() - .into()); + return Err(Error::NotFound("directory not found".into())); } - return get_routes::get_blob(entr, params, controller, ctx, parts); - } - tree = ctx.repo.find_tree(entr.id()); - if !unsanitized_path.ends_with('/') { - return Err(Error::MissingTrailingSlash(parts.uri.path().to_owned())); + if controller.may_write_path(&ctx, parts) { + if params.action == "edit" { + Ok(forms::edit_text_form( + &forms::EditForm::default(), + None, + controller, + &ctx, + parts, + ) + .into()) + } else if params.action == "upload" { + Ok(forms::upload_form(false, controller, &ctx, parts).into()) + } else { + Err(Error::NotFound( + "file not found, but <a href=?action=edit>you can write it</a> or <a href=?action=upload>upload it</a>".into(), + )) + } + } else { + Err(Error::NotFound("file not found".into())) + } } } - - get_routes::view_tree(tree, controller, &ctx, parts) } fn render_link(name: &str, label: &str, active_action: &str) -> String { |