# if we're called with PATH_INFO, we have to strip that
# from the URL to find our real URL
# we make $path_info global because it's also used later on
-my $path_info = $ENV{"PATH_INFO"};
+our $path_info = $ENV{"PATH_INFO"};
if ($path_info) {
$my_url =~ s,\Q$path_info\E$,,;
$my_uri =~ s,\Q$path_info\E$,,;
# (only effective if this variable evaluates to true)
our $export_ok = "++GITWEB_EXPORT_OK++";
+# show repository only if this subroutine returns true
+# when given the path to the project, for example:
+# sub { return -e "$_[0]/git-daemon-export-ok"; }
+our $export_auth_hook = undef;
+
# only allow viewing of repositories also shown on the overview page
our $strict_export = "++GITWEB_STRICT_EXPORT++";
sub check_export_ok {
my ($dir) = @_;
return (check_head_link($dir) &&
- (!$export_ok || -e "$dir/$export_ok"));
+ (!$export_ok || -e "$dir/$export_ok") &&
+ (!$export_auth_hook || $export_auth_hook->($dir)));
}
# process alternate names for backward compatibility
# together during validation: this allows subsequent uses (e.g. href()) to be
# agnostic of the parameter origin
-my %input_params = ();
+our %input_params = ();
# input parameters are stored with the long parameter name as key. This will
# also be used in the href subroutine to convert parameters to their CGI
# XXX: Warning: If you touch this, check the search form for updating,
# too.
-my @cgi_param_mapping = (
+our @cgi_param_mapping = (
project => "p",
action => "a",
file_name => "f",
extra_options => "opt",
search_use_regexp => "sr",
);
-my %cgi_param_mapping = @cgi_param_mapping;
+our %cgi_param_mapping = @cgi_param_mapping;
# we will also need to know the possible actions, for validation
-my %actions = (
+our %actions = (
"blame" => \&git_blame,
"blobdiff" => \&git_blobdiff,
"blobdiff_plain" => \&git_blobdiff_plain,
# finally, we have the hash of allowed extra_options for the commands that
# allow them
-my %allowed_options = (
+our %allowed_options = (
"--no-merges" => [ qw(rss atom log shortlog history) ],
);
# - action
# - hash_parent or hash_parent_base:/file_parent
# - hash or hash_base:/filename
+ # - the snapshot_format as an appropriate suffix
# When the script is the root DirectoryIndex for the domain,
# $href here would be something like http://gitweb.example.com/
$href .= "/".esc_url($params{'project'}) if defined $params{'project'};
delete $params{'project'};
+ # since we destructively absorb parameters, we keep this
+ # boolean that remembers if we're handling a snapshot
+ my $is_snapshot = $params{'action'} eq 'snapshot';
+
# Summary just uses the project path URL, any other action is
# added to the URL
if (defined $params{'action'}) {
$href .= esc_url($params{'hash'});
delete $params{'hash'};
}
+
+ # If the action was a snapshot, we can absorb the
+ # snapshot_format parameter too
+ if ($is_snapshot) {
+ my $fmt = $params{'snapshot_format'};
+ # snapshot_format should always be defined when href()
+ # is called, but just in case some code forgets, we
+ # fall back to the default
+ $fmt ||= $snapshot_fmts[0];
+ $href .= $known_snapshot_formats{$fmt}{'suffix'};
+ delete $params{'snapshot_format'};
+ }
}
# now encode the parameters explicitly
my $input = shift || return undef;
if (!validate_pathname($input) ||
!(-d "$projectroot/$input") ||
- !check_head_link("$projectroot/$input") ||
- ($export_ok && !(-e "$projectroot/$input/$export_ok")) ||
+ !check_export_ok("$projectroot/$input") ||
($strict_export && !project_in_list($input))) {
return undef;
} else {
my ($projlist, $check_forks) = @_;
my @projects;
- my $show_ctags = gitweb_check_feature('ctags');
+ my ($show_ctags) = gitweb_check_feature('ctags');
PROJECT:
foreach my $pr (@$projlist) {
my (@activity) = git_get_last_activity($pr->{'path'});
@projects = sort {$a->{$oi->{'key'}} <=> $b->{$oi->{'key'}}} @projects;
}
- my $show_ctags = gitweb_check_feature('ctags');
+ my ($show_ctags) = gitweb_check_feature('ctags');
if ($show_ctags) {
my %ctags;
foreach my $p (@projects) {
}
# Tag cloud
- my $show_ctags = (gitweb_check_feature('ctags'))[0];
+ my ($show_ctags) = gitweb_check_feature('ctags');
if ($show_ctags) {
my $ctags = git_get_project_ctags($project);
my $cloud = git_populate_project_tagcloud($ctags);
my $fd;
my $ftype;
- gitweb_check_feature('blame')
+ gitweb_check_feature('blame')[0]
or die_error(403, "Blame view not allowed");
die_error(400, "No file name given") unless $file_name;
}
sub git_search {
- gitweb_check_feature('search') or die_error(403, "Search is disabled");
+ gitweb_check_feature('search')[0] or die_error(403, "Search is disabled");
if (!defined $searchtext) {
die_error(400, "Text field is empty");
}
if ($searchtype eq 'pickaxe') {
# pickaxe may take all resources of your box and run for several minutes
# with every query - so decide by yourself how public you make this feature
- gitweb_check_feature('pickaxe')
+ gitweb_check_feature('pickaxe')[0]
or die_error(403, "Pickaxe is disabled");
}
if ($searchtype eq 'grep') {
- gitweb_check_feature('grep')
+ gitweb_check_feature('grep')[0]
or die_error(403, "Grep is disabled");
}