gitweb: parse project/action/hash_base:filename PATH_INFO
This patch enables gitweb to parse URLs with more information embedded in PATH_INFO, reducing the need for CGI parameters. The typical gitweb path is now $project/$action/$hash_base:$file_name or $project/$action/$hash This is mostly backwards compatible with the old-style gitweb paths, $project/$branch[:$filename], except when it was used to access a branch whose name matches a gitweb action. Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com> Acked-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Giuseppe Bilotta committed
Oct 21, 2008 at 21:34 UTC
d8c2882254f0f30e4f44de593c3b3db6a8fccef9
1 file changed
+39
-7
gitweb/gitweb.perl
+39
-7
@@ -534,23 +534,55 @@ sub evaluate_path_info {
534
return if $input_params{'action'};
535
$path_info =~ s,^\Q$project\E/*,,;
536
537
+ # next, check if we have an action
538
+ my $action = $path_info;
539
+ $action =~ s,/.*$,,;
540
+ if (exists $actions{$action}) {
541
+ $path_info =~ s,^$action/*,,;
542
+ $input_params{'action'} = $action;
543
+ }
544
+
545
+ # list of actions that want hash_base instead of hash, but can have no
546
+ # pathname (f) parameter
547
+ my @wants_base = (
548
+ 'tree',
549
+ 'history',
550
+ );
551
+
552
my ($refname, $pathname) = split(/:/, $path_info, 2);
553
if (defined $pathname) {
539
- # we got "project.git/branch:filename" or "project.git/branch:dir/"
540
- # we could use git_get_type(branch:pathname), but it needs $git_dir
554
+ # we got "branch:filename" or "branch:dir/"
555
+ # we could use git_get_type(branch:pathname), but:
556
+ # - it needs $git_dir
557
+ # - it does a git() call
558
+ # - the convention of terminating directories with a slash
559
+ # makes it superfluous
560
+ # - embedding the action in the PATH_INFO would make it even
561
+ # more superfluous
562
$pathname =~ s,^/+,,;
563
if (!$pathname || substr($pathname, -1) eq "/") {
543
- $input_params{'action'} = "tree";
564
+ $input_params{'action'} ||= "tree";
565
$pathname =~ s,/$,,;
566
} else {
546
- $input_params{'action'} = "blob_plain";
567
+ $input_params{'action'} ||= "blob_plain";
568
}
569
$input_params{'hash_base'} ||= $refname;
570
$input_params{'file_name'} ||= $pathname;
571
} elsif (defined $refname) {
551
- # we got "project.git/branch"
552
- $input_params{'action'} = "shortlog";
553
- $input_params{'hash'} ||= $refname;
572
+ # we got "branch". In this case we have to choose if we have to
573
+ # set hash or hash_base.
574
+ #
575
+ # Most of the actions without a pathname only want hash to be
576
+ # set, except for the ones specified in @wants_base that want
577
+ # hash_base instead. It should also be noted that hand-crafted
578
+ # links having 'history' as an action and no pathname or hash
579
+ # set will fail, but that happens regardless of PATH_INFO.
580
+ $input_params{'action'} ||= "shortlog";
581
+ if (grep { $_ eq $input_params{'action'} } @wants_base) {
582
+ $input_params{'hash_base'} ||= $refname;
583
+ } else {
584
+ $input_params{'hash'} ||= $refname;
585
+ }
586
}
587
}
588
evaluate_path_info();