diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 85 |
1 files changed, 22 insertions, 63 deletions
diff --git a/src/main.rs b/src/main.rs index d521087..30f018b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ use clap::Clap; use controller::Controller; -use git2::BranchType; use git2::Commit; use git2::ObjectType; use git2::Oid; @@ -103,7 +102,19 @@ async fn main() { if args.multiuser { serve(MultiUserController::new(&repo), args).await; } else { - serve(SoloController, args).await; + serve( + SoloController(Branch( + repo.find_reference("HEAD") + .unwrap() + .symbolic_target() + .unwrap() + .strip_prefix("refs/heads/") + .unwrap() + .to_owned(), + )), + args, + ) + .await; } } @@ -195,7 +206,7 @@ pub enum Error { // TODO: use Redirect instead /// Missing trailing slash. - MissingTrailingSlash(Parts), + MissingTrailingSlash(String), } impl From<Utf8Error> for Error { @@ -223,10 +234,10 @@ async fn service<C: Controller>( Error::Forbidden(msg) => (403, msg), Error::NotFound(msg) => (404, msg), Error::Internal(msg) => (500, msg), - Error::MissingTrailingSlash(parts) => { + Error::MissingTrailingSlash(path) => { return Builder::new() .status(StatusCode::FOUND) - .header("location", format!("{}/", parts.uri.path())) + .header("location", format!("{}/", path)) .body("redirecting".into()) .unwrap(); } @@ -321,11 +332,6 @@ impl From<git2::Error> for Error { } } -/// Builds a URL path from a given Git revision and filepath. -fn build_url_path(rev: &Branch, path: &str) -> String { - format!("/~{}/{}", rev.0, path) -} - #[derive(Eq, PartialEq, Hash, Clone)] pub struct Branch(String); @@ -341,7 +347,6 @@ async fn build_response<C: Controller>( parts: Parts, body: Body, ) -> Result<Response, Error> { - controller.before_route(&parts)?; let unsanitized_path = percent_decode_str(parts.uri.path()) .decode_utf8() .map_err(|_| Error::BadRequest("failed to percent-decode path as UTF-8".into()))? @@ -349,58 +354,11 @@ async fn build_response<C: Controller>( let repo = Repository::open_bare(env::current_dir().unwrap()).unwrap(); - if parts.uri.path() == "/" { - // TODO: add domain name to title? - let mut page = Page { - title: "GitPad".into(), - controller, - parts: &parts, - body: String::new(), - header: None, - }; - - let branches: Vec<_> = repo.branches(Some(BranchType::Local))?.collect(); - - page.body.push_str("This GitPad instance has "); - - if branches.is_empty() { - page.body.push_str("no branches yet."); - - if !args.multiuser { - page.body.push_str("<p>Start by creating for example <a href='/~main/todo.md'>/~main/todo.md</a>.</p>"); - } - } else { - page.body.push_str("the following branches:"); - page.body.push_str("<ul>"); - for (branch, _) in repo.branches(Some(BranchType::Local))?.flatten() { - page.body.push_str(&format!( - "<li><a href='~{0}/'>~{0}</a></li>", - html_escape(branch.name()?.unwrap()) - )); - } - page.body.push_str("</ul>"); - } - - return Ok(page.into()); + if let Some(resp) = controller.before_route(&parts, &repo) { + return resp; } - let mut iter = unsanitized_path.splitn(3, '/'); - iter.next(); - let rev = iter.next().unwrap(); - if !rev.starts_with('~') { - return Err(Error::NotFound( - "branch name must be prefixed a tilde (~)".into(), - )); - } - let rev = &rev[1..]; - if rev.trim().is_empty() { - return Err(Error::NotFound("invalid branch name".into())); - } - let rev = Branch(rev.to_owned()); - let unsanitized_path = match iter.next() { - Some(value) => value, - None => return Err(Error::MissingTrailingSlash(parts)), - }; + let (rev, unsanitized_path) = controller.parse_url_path(&unsanitized_path)?; let mut comps = Vec::new(); @@ -478,7 +436,8 @@ async fn build_response<C: Controller>( .status(StatusCode::FOUND) .header( "location", - build_url_path(&ctx.branch, unsanitized_path.trim_end_matches('/')), + controller + .build_url_path(&ctx.branch, unsanitized_path.trim_end_matches('/')), ) .body("redirecting".into()) .unwrap()); @@ -488,7 +447,7 @@ async fn build_response<C: Controller>( tree = ctx.repo.find_tree(entr.id()); if !unsanitized_path.ends_with('/') { - return Err(Error::MissingTrailingSlash(ctx.parts)); + return Err(Error::MissingTrailingSlash(ctx.parts.uri.path().to_owned())); } } |