FrontEnd GNU/NONGNU host redirection

Savannah handles three types of hosts redirection:

  1. Shortcut URL to full URL (e.g. *.sv.gnu.org => *.savannah.gnu.org).
  2. *.gnu.org <=> *.nongnu.org, depending on group type.
  3. automatic-login to both savannah.gnu.org and savannah.nongnu.org
  4. attachment requests from old URLs to dedicated domain (savannah.gnu.org/file/* => file.savannah.gnu.org/file/*, savannah.gnu.org/submission-uploads/ => file.savannah.gnu.org/submission-uploads/) and non-file requests from file.savannah.*.org to the original domain.

Shortcut URL redirection

Shortcurt URL redirection (.e.g *.sv.gnu.org => *.savannah.gnu.org) is handled entirely in the web server configuration.

This would've been simple, if it were't for two complications:

  1. For HTTP, all URLs should be redirected as-is with full URI (e.g. http://sv.gnu.org/p/coreutils should redirect to http://savannah.gnu.org/p/coreutils, not just to http://savannah.gnu.org) EXCEPT the .well-known directory, which must not be redirected because of the use of Let's-Encrypt certboot (i.e. http://sv.gnu.org/.well-known/XXX must be valid and not redirected). See https for details about the certbot configuration.

  2. For HTTPS, slightly different configuration is set needed on whether it's gnu or nongnu domain, while still requiring that https://sv.gnu.org/p/coreutils redirects to the full https://savannah.gnu.org/p/coreutils.

FIXME: Document the nginx setup for the production website.

GNU/NONGNU redirection

gnu/nongnu redirection is handled entirely in the PHP code, based on whether the viewed group belongs in GNU or not (sometimes referred to as 'brother' site in the code/config files).

Example: when users visit https://savannah.nongnu.org/projects/coreutils they are redirected to https://savannah.gnu.org/projects/coreutils because coreutils is an official GNU package.

Enabling/Disabling redirection

In /etc/savane/savane.conf.php, setting the boolean variable $sys_debug_nobasehost to true disables redirection completely.

Group-based redirection

When a page is visited (if it relates to a hosted group), the function $project->getTypeBaseHost() is called and returns the host that is relevant to the viewed group (based on the group type).

The values on the production site are:

mysql> select type_id, name, base_host from group_type ;
+---------+------------------------------------+---------------------+
| type_id | name                               | base_host           |
+---------+------------------------------------+---------------------+
|       1 | Official GNU software              | savannah.gnu.org    |
|       2 | non-GNU software and documentation | savannah.nongnu.org |
|       3 | www.gnu.org portions               | savannah.gnu.org    |
|       4 | GUG                                | savannah.nongnu.org |
|       6 | www.gnu.org translation teams      | savannah.gnu.org    |
+---------+------------------------------------+---------------------+
5 rows in set (0.00 sec)

PHP Code

The variable $sys_debug_nobasehost is mentioned in the following files:

in ./frontend/php/include/init.php:

# if we are at wrong url, redirect
if (!$sys_debug_nobasehost && strcasecmp($_SERVER['HTTP_HOST"], $project->getTypeBaseHost()) != 0 && $project->getTypeBaseHost())
{
  header ("Location: http".(session_issecure()?'s":'")."://".$project->getTypeBaseHost().$_SERVER['PHP_SELF"]);
  exit;
}

in ./frontend/php/include/project_home/php:

if (strcasecmp($_SERVER['HTTP_HOST"], $project->getTypeBaseHost()) != 0 && $project->getTypeBaseHost())
 {
  header ('Location: http".(session_issecure()?'s":'").'://".$project->getTypeBaseHost().$_SERVER["REQUEST_URI"]);
  exit;
 }

Auto-login to 'brother' site

When a user visits the login page on https://savannah.gnu.org/account/login.php, there's is a check-box at the bottom of the page asking for "Login also in savannah.nongnu.org".

This is called a 'brother' site in the code and config files. It is implemented using several HTTP redirects from one site to the other (e.g from the default 'savannah.gnu.org' to 'savannah.nongnu.org') sending hashed session IDs back and forth (counting on the fact that both sites run on the same physical server and share PHP session cookies).

In /etc/savane/savane.conf.php there are these two variables:

$sys_default_domain="savannah.gnu.org";
$sys_brother_domain="savannah.nongnu.org";

In the correspnding /etc/savane/nongnu-conf/savane.conf.php the default/brother hosts are swapped:

$sys_default_domain="frontend0.savannah.nongnu.org";
$sys_https_host="$sys_default_domain";
$sys_brother_domain="frontend0.savannah.gnu.org";

The nginx configuration must be set appropriately for each domain.

NOTE: If the "login to [brother] set" checkbox is set, Savannah will do the redirection even if the variable is set ($sys_debug_nobasehost=true). If you forget to update the settings in nongnu-conf/savane.conf.php, you might get redirected to the real website (e.g. savannah.nongnu.org), which will not only confuse things, but will also cause troubles with cookie authentication (you'll see an error message saying "Savane thinks your cookies are not activated for XXX" from login.php).

The 'brother' login sequences is used in two files: ./frontend/php/account/login.php and ./frontend/php/account/su.php (su implements "become superuser" feature for admins).

The gist is:

  1. After successful login to savannah.gnu.org, login.php will redirect to: https://savannah.NONGNU.org/account/login.php?session_uid=94790&session_hash=XXXXXXXXXX&cookie_for_a_year=&from_brother=1&login=1&stay_in_ssl=1&brotherhood=1&uri=%2F

  2. login.php (this time called on host savannah.nongnu.org) will see that $from_brother=1, and will set the cookie/session for this domain as well, then redirect back to savannah.gnu.org/.

File redirection

Since July 2020, Savannah serves user-supplied files from a separate domain (file.savannah.{non,}gnu.org) for security reasons. Old URLs are redirected to that domain, non-file requests are redirected to the main domain (savannah.{non,}gnu.org).