gitweb: Even more support for PATH_INFO based URLs

Now the following types of path based URLs are supported:

* project              overview (summary) page of project
* project/branch       shortlog of branch
* project/branch:file  file in branch, blob_plain view
* project/branch:dir/  directory listing of dir in branch, tree view

The following shortcuts works (see explanation below):

* project/branch:      directory listing of branch, main tree view
* project/:file        file in HEAD (raw)
* project/:dir/        directory listing of dir in HEAD
* project/:            directory listing of project's HEAD

We use ':' as separator between branch (ref) name and file name
(pathname) because valid branch (ref) name cannot have ':' inside.
This limit applies to branch name only. This allow for hierarchical
branches e.g. topic branch 'topic/subtopic', separate remotes
tracking branches e.g. 'refs/remotes/origin/HEAD', and discriminate
between head (branch) and tag with the same name.

Empty branch should be interpreted as HEAD.

If pathname (the part after ':') ends with '/', we assume that pathname
is name of directory, and we want to show contents of said directory
using "tree" view. If pathname is empty, it is equivalent to '/' (top
directory).

If pathname (the part after ':') does not end with '/', we assume that
pathname is name of file, and we show contents of said file using
"blob_plain" view.

Pathname is stripped of leading '/', so we can use ':/' to separate
branch from pathname. The rationale behind support for PATH_INFO based
URLs was to support project web pages for small projects: just create
an html branch and then use an URL like
  http://nowhere.com/gitweb.cgi/project.git/html:/index.html
The ':/' syntax allow for working links between .html files served
in such way, e.g. <a href="main.html"> link inside "index.html"
would get
  http://nowhere.com/gitweb.cgi/project.git/html:/main.html.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Jakub Narebski 2006-09-20 00:49:51 +02:00 коммит произвёл Junio C Hamano
Родитель 44d2775a98
Коммит cd90e75ff4
1 изменённых файлов: 20 добавлений и 9 удалений

Просмотреть файл

@ -274,13 +274,16 @@ sub evaluate_path_info {
return if defined $project;
my $path_info = $ENV{"PATH_INFO"};
return if !$path_info;
$path_info =~ s,(^/|/$),,gs;
$path_info = validate_input($path_info);
$path_info =~ s,^/+,,;
return if !$path_info;
# find which part of PATH_INFO is project
$project = $path_info;
$project =~ s,/+$,,;
while ($project && !-e "$projectroot/$project/HEAD") {
$project =~ s,/*[^/]*$,,;
}
# validate project
$project = validate_input($project);
if (!$project ||
($export_ok && !-e "$projectroot/$project/$export_ok") ||
($strict_export && !project_in_list($project))) {
@ -289,15 +292,23 @@ sub evaluate_path_info {
}
# do not change any parameters if an action is given using the query string
return if $action;
if ($path_info =~ m,^$project/([^/]+)/(.+)$,) {
# we got "project.git/branch/filename"
$action ||= "blob_plain";
$hash_base ||= validate_input($1);
$file_name ||= validate_input($2);
} elsif ($path_info =~ m,^$project/([^/]+)$,) {
$path_info =~ s,^$project/*,,;
my ($refname, $pathname) = split(/:/, $path_info, 2);
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
$pathname =~ s,^/+,,;
if (!$pathname || substr($pathname, -1) eq "/") {
$action ||= "tree";
} else {
$action ||= "blob_plain";
}
$hash_base ||= validate_input($refname);
$file_name ||= validate_input($pathname);
} elsif (defined $refname) {
# we got "project.git/branch"
$action ||= "shortlog";
$hash ||= validate_input($1);
$hash ||= validate_input($refname);
}
}
evaluate_path_info();