Skip to contentSkip to conversation

gitweb: Even more support for PATH_INFO based URLs

PATCH In review Jakub Narebski 3 participants 4 messages Jun 15, 2016

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---
Alternatively we could use git-cat-file -t (git_get_type subroutine) to distinguish between trees and files (blobs), but first it would slow gitweb somewhat (additional fork), and second git_get_type assumes that $git_dir is set... and this variable is defined later!

See also:
"[PATCH] gitweb: more support for PATH_INFO based URLs"
Message-ID: <[email protected]>
http://permalink.gmane.org/gmane.comp.version-control.git/27133
(this email should be probably posted in this thread)

 gitweb/gitweb.perl |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)
gitweb/gitweb.perl +20 -9
index 9445fa7..839b232 100755
@@ -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();
Signature · 1 line
1.4.2.1
#1 lore raw

hoi :)

Quoted 7 lines · Jakub Narebski

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
Quoted 6 lines

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

very nice! thanks a lot!

Signature · 1 line
Martin Waitz
#2 lore raw
In reply to Jakub Narebski

Hi,

Dear diary, on Wed, Sep 20, 2006 at 12:49:51AM CEST, I got a letter where Jakub Narebski <[email protected]> said that...

Quoted 7 lines

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
Quoted 6 lines

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

I haven't followed this stuff carefully but just to confirm, there is
currently no way to persuade gitweb to actually produce such links, right?

I like pathinfo and would like to use it for repo.or.cz's gitweb.

Signature · 5 lines
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
#3 lore raw
Quoted 16 lines · Petr Baudis

Dear diary, on Wed, Sep 20, 2006 at 12:49:51AM CEST, I got a letter where Jakub Narebski <[email protected]> said that...

Quoted 7 lines

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
Quoted 6 lines

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
Quoted 5 lines

I haven't followed this stuff carefully but just to confirm, there is
currently no way to persuade gitweb to actually produce such links, right?

I like pathinfo and would like to use it for repo.or.cz's gitweb.

Well, all inner links go through href() subroutine, so this is where you would want to make changes. Having project in pathinfo would be easy, having branch/ref harder because it might be in hash, or in hash_base parameter.

Perhaps we should use

	my $path_info = $ENV{MOD_PERL} ? $r->path_info() : $ENV{PATH_INFO};
Signature · 2 lines
Jakub Narebski
Poland