Answering to different addresses with Chamilo

One possible annoying element of Chamilo is it can only answer to one address at a time. This simply comes from a very old codebase and the fact that, at some point in the past, it wasn't that easy to get the address from the URL or the HTTP headers in a reliable way. Nowadays, though, it's completely reliable to say that your host is (in PHP) $_SERVER['HTTP_HOST'], so you could hack the configuration file of Chamilo (main/inc/conf/configuration.php or app/config/configuration.php in Chamilo 1.10) like this:
  $_configuration['root_web'] = 'http://my.chamilo19.net/';
  if (!empty($_SERVER['HTTP_HOST'])) {
    $_configuration['root_web'] = 'http://'.$_SERVER['HTTP_HOST'].'/';
  }
This might have a security impact, we are still assessing this. However, it is likely that this does not really impact security, as other similar systems (like Drupal, Joomla, etc) also let the HTTP_HOST determine the web root path. One alteration to this would be to manually allow for the definition of a "list" of authorized hosts. If we cannot find any clear reason to prevent the use of this technique in Chamilo, it is likely versions starting from 1.10 will rely on this to avoid the strict dependency on the host defined in $_configuration['root_web']. There will likely be a requirement on $_SERVER['SERVER_PROTOCOL'] as well to identify cases where we use HTTPS (SSL certificates). Kudos to GMP Perú for passing this requirement on to us so we could work on it and find a good solution. BT#5737 2014-02 edit: Another customer has reported that, when using what they call a "safe browser" (proprietary piece of software, as far as we could tell), they ran into issues when moving to the next question in an exam. Apparently, the so called "safe browser" tries to force HTTPS on top of a non-HTTPS communication, or to proxy the URLs in some way. This falls into the same kind of issues as above, as the server does not accept different URLs.
To fix this, we had to include HTTPS processing to the above code:
 
  $_configuration['root_web'] = 'http://my.chamilo19.net/';
  if (!empty($_SERVER['HTTP_HOST'])) {
    if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
      $_configuration['root_web'] = 'https://'.$_SERVER['HTTP_HOST'].'/';
    } else {
      $_configuration['root_web'] = 'http://'.$_SERVER['HTTP_HOST'].'/';
    }
  }

If you thought this couldn't get even more complex, we have seen some cases where, because it is behind a reverse-proxy in HTTPS, Chamilo doesn't receive the $_SERVER['HTTPS'] element, but rather $_SERVER['HTTP_X_FORWARDED_PROTO'] with a value of 'https'. In this case, you have to add more conditions to your block:
  $_configuration['root_web'] = 'http://my.chamilo19.net/';
  if (!empty($_SERVER['HTTP_HOST'])) {
      if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') 
        or (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) { 
          $_configuration['root_web'] = 'https://'.$_SERVER['HTTP_HOST'].'/';
      } else {
          $_configuration['root_web'] = 'http://'.$_SERVER['HTTP_HOST'].'/';
      }
  } 
  2014-04 edit: It seems that more and more weird requirements are appearing around this. Another customer wants to support both a local IP address with a sub-folder in which Chamilo lies (for example http://172.34.13.45/chamilo) *and* a normal public domain like http://my.chamilo19.net/. This is a slight issue in Chamilo, as we clearly differenciate between installations in a subfolder and installations in a "root" folder (o better said, "root domain path"). Nevertheless, the following has been lightly tested and seems to be working just fine, as the only difference between sub-folder mode and root folder mode is the url_append element of the $_configuration array.
  // "/chamilo" is the subfolder, "172.34.13.45" is the local IP,
  // "my.chamilo19.net" is the "root domain"
  $_configuration['url_append'] = '/chamilo';
  $_configuration['root_web'] = 'http://172.34.13.45/chamilo/';
  if (!empty($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] != '172.34.13.45') {
    if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
      $_configuration['root_web'] = 'https://my.chamilo19.net/';
    } else {
      $_configuration['root_web'] = 'http://my.chamilo19.net/';
    }
    $_configuration['url_append'] = '';
  }
This type of configuration will NOT work, however, with a single SSL certificate, and will definitely not work with the IP address (you need to define a real host name to get a certificate for).

Special case for Wamp

It has been reported to us that, when using Wamp on Windows with no particular domain definition (like http://localhost/), Wamp actually kind of forces you to use a sub-directory configuration like this: http://localhost/chamilo/ If this is the case, a weird effect can be observed where the normal configuration of Chamilo and in particular of the "URL append" setting will not work. After some trial and error, we can confirm that the following worked at least on one Wamp installation (adapt whatever you need to adapt):
  $_configuration['root_web'] = 'http://localhost/chamilo/';
  if (!empty($_SERVER['HTTP_HOST'])) {
    $_configuration['root_web'] = 'http://'.$_SERVER['HTTP_HOST'].'/chamilo/';
  }
  $_configuration['url_append'] = '';
There is no logical explanation for this yet, but know that this worked and decide whether you want to know why or not. Also, installing on Wamp requires you, if using Apache 2.4.*, to configure additional stuff in your httpd.conf config file for Apache, including a "Require all granted" statement. This is covered largely by other tutorial, like this one here: http://stackoverflow.com/a/23385021/6499848

Nightmare level: Configuring through SSH tunnels

So... sometimes you might get a customer that asks you to do that on a server in their infrastructure with no HTTP nor HTTPS access to the Chamilo portal whatsoever. Fear not! Here is the solution! First of all, you might get inspired by the information in this other article of ours about SSH tunnelling. In particular the second section "Opening a browser". Basically, if your computer is A, that you connect with SSH to server B at your customer's datacenter and then connect from there to server C where Chamilo should be installed, you can do the downloading and server setup simply through SSH. But then you will need (ideally, because you could also install it headless with Chash) a browser to connect to the portal and proceed with the installation. To do that, you'll have to launch the following command from your computer ssh 8180:C.C.C.C:80 user@B And then you can open your browser on http://localhost:8180 and you should see the install screen of Chamilo. Now there are *many* variations to that. The first one is that "localhost" should actually match the name of your Chamilo portal on server C. This is not often the case, and if it was you would probably not be installing a real production server. To enable you to load server C with the proper host, you have to trick your own computer into believing that he answers to server C's domain name (let's say it's chamilo.c.com). You do that by adding the host in your /etc/hosts file, on the "127.0.0.1" line. This way, you set your browser to load http://chamilo.c.com:8081/ and you will magically get on Chamilo's installation page, this time with the right domain name, so you can configure the installer properly? But in order for Chamilo to accept the concept of an additional port on the URL (8081 in this case), you will need to configure one of these smart redirections in the first or second sections of this article (second if you use HTTPS). If you *do* use HTTPS, don't forget to use it in your browser as well: https://chamilo.c.com:8081/, otherwise Chamilo might not detect it as HTTPS and install it in HTTP by default (which might cause issues to access it afterwards). Don't forget, during the installation, to remove the port from the Chamilo URL that the installer will automatically detect. Clearly, you don't want Chamilo to only answer on a URL with :8081 at the end of the domain name! That short explanation, if you understand it, should get you out of trouble and into configuring Chamilo properly.