Merge branch 'gb/gitweb-pathinfo'
* gb/gitweb-pathinfo: gitweb: generate parent..current URLs gitweb: parse parent..current syntax from PATH_INFO gitweb: use_pathinfo filenames start with / gitweb: generate project/action/hash URLs gitweb: parse project/action/hash_base:filename PATH_INFO
This commit is contained in:
commit
7429ed2bad
@ -534,23 +534,87 @@ sub evaluate_path_info {
|
||||
return if $input_params{'action'};
|
||||
$path_info =~ s,^\Q$project\E/*,,;
|
||||
|
||||
my ($refname, $pathname) = split(/:/, $path_info, 2);
|
||||
# next, check if we have an action
|
||||
my $action = $path_info;
|
||||
$action =~ s,/.*$,,;
|
||||
if (exists $actions{$action}) {
|
||||
$path_info =~ s,^$action/*,,;
|
||||
$input_params{'action'} = $action;
|
||||
}
|
||||
|
||||
# list of actions that want hash_base instead of hash, but can have no
|
||||
# pathname (f) parameter
|
||||
my @wants_base = (
|
||||
'tree',
|
||||
'history',
|
||||
);
|
||||
|
||||
# we want to catch
|
||||
# [$hash_parent_base[:$file_parent]..]$hash_parent[:$file_name]
|
||||
my ($parentrefname, $parentpathname, $refname, $pathname) =
|
||||
($path_info =~ /^(?:(.+?)(?::(.+))?\.\.)?(.+?)(?::(.+))?$/);
|
||||
|
||||
# first, analyze the 'current' part
|
||||
if (defined $pathname) {
|
||||
# we got "project.git/branch:filename" or "project.git/branch:dir/"
|
||||
# we could use git_get_type(branch:pathname), but it needs $git_dir
|
||||
# we got "branch:filename" or "branch:dir/"
|
||||
# we could use git_get_type(branch:pathname), but:
|
||||
# - it needs $git_dir
|
||||
# - it does a git() call
|
||||
# - the convention of terminating directories with a slash
|
||||
# makes it superfluous
|
||||
# - embedding the action in the PATH_INFO would make it even
|
||||
# more superfluous
|
||||
$pathname =~ s,^/+,,;
|
||||
if (!$pathname || substr($pathname, -1) eq "/") {
|
||||
$input_params{'action'} = "tree";
|
||||
$input_params{'action'} ||= "tree";
|
||||
$pathname =~ s,/$,,;
|
||||
} else {
|
||||
$input_params{'action'} = "blob_plain";
|
||||
# the default action depends on whether we had parent info
|
||||
# or not
|
||||
if ($parentrefname) {
|
||||
$input_params{'action'} ||= "blobdiff_plain";
|
||||
} else {
|
||||
$input_params{'action'} ||= "blob_plain";
|
||||
}
|
||||
}
|
||||
$input_params{'hash_base'} ||= $refname;
|
||||
$input_params{'file_name'} ||= $pathname;
|
||||
} elsif (defined $refname) {
|
||||
# we got "project.git/branch"
|
||||
$input_params{'action'} = "shortlog";
|
||||
$input_params{'hash'} ||= $refname;
|
||||
# we got "branch". In this case we have to choose if we have to
|
||||
# set hash or hash_base.
|
||||
#
|
||||
# Most of the actions without a pathname only want hash to be
|
||||
# set, except for the ones specified in @wants_base that want
|
||||
# hash_base instead. It should also be noted that hand-crafted
|
||||
# links having 'history' as an action and no pathname or hash
|
||||
# set will fail, but that happens regardless of PATH_INFO.
|
||||
$input_params{'action'} ||= "shortlog";
|
||||
if (grep { $_ eq $input_params{'action'} } @wants_base) {
|
||||
$input_params{'hash_base'} ||= $refname;
|
||||
} else {
|
||||
$input_params{'hash'} ||= $refname;
|
||||
}
|
||||
}
|
||||
|
||||
# next, handle the 'parent' part, if present
|
||||
if (defined $parentrefname) {
|
||||
# a missing pathspec defaults to the 'current' filename, allowing e.g.
|
||||
# someproject/blobdiff/oldrev..newrev:/filename
|
||||
if ($parentpathname) {
|
||||
$parentpathname =~ s,^/+,,;
|
||||
$parentpathname =~ s,/$,,;
|
||||
$input_params{'file_parent'} ||= $parentpathname;
|
||||
} else {
|
||||
$input_params{'file_parent'} ||= $input_params{'file_name'};
|
||||
}
|
||||
# we assume that hash_parent_base is wanted if a path was specified,
|
||||
# or if the action wants hash_base instead of hash
|
||||
if (defined $input_params{'file_parent'} ||
|
||||
grep { $_ eq $input_params{'action'} } @wants_base) {
|
||||
$input_params{'hash_parent_base'} ||= $parentrefname;
|
||||
} else {
|
||||
$input_params{'hash_parent'} ||= $parentrefname;
|
||||
}
|
||||
}
|
||||
}
|
||||
evaluate_path_info();
|
||||
@ -699,14 +763,61 @@ sub href (%) {
|
||||
|
||||
my ($use_pathinfo) = gitweb_check_feature('pathinfo');
|
||||
if ($use_pathinfo) {
|
||||
# use PATH_INFO for project name
|
||||
# try to put as many parameters as possible in PATH_INFO:
|
||||
# - project name
|
||||
# - action
|
||||
# - hash_parent or hash_parent_base:/file_parent
|
||||
# - hash or hash_base:/filename
|
||||
|
||||
# When the script is the root DirectoryIndex for the domain,
|
||||
# $href here would be something like http://gitweb.example.com/
|
||||
# Thus, we strip any trailing / from $href, to spare us double
|
||||
# slashes in the final URL
|
||||
$href =~ s,/$,,;
|
||||
|
||||
# Then add the project name, if present
|
||||
$href .= "/".esc_url($params{'project'}) if defined $params{'project'};
|
||||
delete $params{'project'};
|
||||
|
||||
# Summary just uses the project path URL
|
||||
if (defined $params{'action'} && $params{'action'} eq 'summary') {
|
||||
# Summary just uses the project path URL, any other action is
|
||||
# added to the URL
|
||||
if (defined $params{'action'}) {
|
||||
$href .= "/".esc_url($params{'action'}) unless $params{'action'} eq 'summary';
|
||||
delete $params{'action'};
|
||||
}
|
||||
|
||||
# Next, we put hash_parent_base:/file_parent..hash_base:/file_name,
|
||||
# stripping nonexistent or useless pieces
|
||||
$href .= "/" if ($params{'hash_base'} || $params{'hash_parent_base'}
|
||||
|| $params{'hash_parent'} || $params{'hash'});
|
||||
if (defined $params{'hash_base'}) {
|
||||
if (defined $params{'hash_parent_base'}) {
|
||||
$href .= esc_url($params{'hash_parent_base'});
|
||||
# skip the file_parent if it's the same as the file_name
|
||||
delete $params{'file_parent'} if $params{'file_parent'} eq $params{'file_name'};
|
||||
if (defined $params{'file_parent'} && $params{'file_parent'} !~ /\.\./) {
|
||||
$href .= ":/".esc_url($params{'file_parent'});
|
||||
delete $params{'file_parent'};
|
||||
}
|
||||
$href .= "..";
|
||||
delete $params{'hash_parent'};
|
||||
delete $params{'hash_parent_base'};
|
||||
} elsif (defined $params{'hash_parent'}) {
|
||||
$href .= esc_url($params{'hash_parent'}). "..";
|
||||
delete $params{'hash_parent'};
|
||||
}
|
||||
|
||||
$href .= esc_url($params{'hash_base'});
|
||||
if (defined $params{'file_name'} && $params{'file_name'} !~ /\.\./) {
|
||||
$href .= ":/".esc_url($params{'file_name'});
|
||||
delete $params{'file_name'};
|
||||
}
|
||||
delete $params{'hash'};
|
||||
delete $params{'hash_base'};
|
||||
} elsif (defined $params{'hash'}) {
|
||||
$href .= esc_url($params{'hash'});
|
||||
delete $params{'hash'};
|
||||
}
|
||||
}
|
||||
|
||||
# now encode the parameters explicitly
|
||||
|
Loading…
Reference in New Issue
Block a user