Projects

Projects

Tags


Pretty URLs when using Fossil with Apache

TL;DR:

.htacces
RewriteEngine on
FallbackResource /index.cgi
index.cgi
#!/usr/bin/fossil
repository: /home/<USER>/<DIR>/<REPO>.fossil
setenv: SCRIPT_NAME=index.cgi

Background

Apache HTTPD is an open source web server which currently dominates the market share of internet web servers. Supporting numerous plug-ins and is extremely configurable to a fault. Apache configuration is a nightmare of possibilities, sometimes there is more than one way to achieve the same result and sometimes two seemly unrelated options conflict with each other. URL rewriting is one of these nightmares.

Fossil is a distributed version control like Git. Easier to use, more features, and a single lightweight executable are some of the reasons why I think Fossil is superior to Git.

The Problem

Fossil has the ability to be invoked as a CGI Script by Apache. Documentation on how to set this up can be found here:

Following the documentation and using Apache, the script name will appear in the URL:

https://my.site/index.cgi/timeline

A better URL would be:

https://my.site/timeline

The Solution

The most natural solution would be to have Apache rewrite the URL. In fact, that was my first solution. The problem with rewriting the URL is you had to modify two files when setting up another Fossil repository. And then there is the Regular Expression syntax, not to mention the redirect flags.

Instead of rewriting the URL, define a FallbackResource. If the Fossil CGI Script name is index.cgi, the .htaccess file would look like this:

.htacces
RewriteEngine on
FallbackResource /index.cgi

The above .htaccess can be used with any Fossil repository as long as the CGI Script name is index.cgi. However, that is just part one. Part two is the Fossil configuration and the secret sauce is:

setenv: SCRIPT_NAME=index.cgi

This sets the SCRIPT_NAME environment variable to the CGI Script name of index.cgi. A complete index.cgi script would look something like the following:

index.cgi
#!/usr/bin/fossil
# Replace:
# - <USER> with the username
# - <DIR> with the path to the Fossil repositories
# - <REPO> with the name of the Fossil repository
repository: /home/<USER>/<DIR>/<REPO>.fossil
setenv: SCRIPT_NAME=index.cgi

When combined, Apache will load index.cgi for all invalid URLs. (Which is pretty much all of them.) The index.cgi script will set the SCRIPT_NAME so that Fossil knows how it was invoked. And Fossil will parse the URL as expected. Magic!