For a reason I'll bore you with later, it was necessary for me to experiment with displaying the content from a particular Drupal subsite, even though the actual domain name being accessed pointed to the "default" site. When I found a way to do it, it was definitely one of those "oh my God, I can't believe this works" moments. I thought I'd share it with you all in case others can make use of it.. It's not totally performant so you probably shouldn't use it as the "primary" way to access a Drupal subsite, but it should work in a hitch.
It's not a module, because this magic needs to happen well before modules are loaded in the Drupal bootstrapping process; so we've got to hack settings.php. I've never been a fan of settings.php hacks; they strike me as inelegant and desperate. But this works.
The hack basically works by letting you specify the desired subsite as part of the query string. Let's say you have a Drupal installation at http://example.com/ and a subsite at http://example.net/. The example.net subsite is defined by a directory simply named "example.net" in the "sites" directory; the "example.com" site is defined by the "default" directory and the "settings.php" file therein. With this hack, by going to http://example.com/~example.net, you'll see example.net's front page. Of course, paths work too; http://example.com/~example.net/user will be the equivalent of http://example.net/user. (Note that if you're not using Clean URLs, you'll have to add the "~example.net/" part to the "q=" part of the query string: so "http://example.com/?q=~example.net/user" in the latter example). Some additional hackiness by way of a custom_url_rewrite_outbound() make sure that menu items and such will still work.
Okay, so here's the hack. This needs to go at the end of the settings.php file in the "default" directory. Be warned that this essentially means that we're including two settings.php files, the default one and the subsite's one, so there's the possibility of remnant data in the former file sticking around for the session which may not belong there - and if the subsite's settings.php has its own custom_url_rewrite_outbound() declaration, PHP's gonna barf out a "can't redeclare function" on you. And remember, it goes at the end of the default "settings.php" file!
<?php
// If a "user directory" is found…
if (isset($_GET['q']) && preg_match('-~([^/.][^/]*)(/(.+))?-', $_GET['q'], $matches)) {
// Remember the user directory
global $rewrite_prefix;
$rewrite_prefix = $matches[1];
// Reset $_GET['q']
$_GET['q'] = isset($matches[3]) ? $matches[3] : '';
// Reset $base_url and related variables
$http_host = $_SERVER['HTTP_HOST'];
$_SERVER['HTTP_HOST'] .= '.' . $matches[1];
require_once conf_path(TRUE, TRUE) . '/settings.php';
// Restore $_SERVER['HTTP_HOST'] (may not be necessary, but doesn't hurt)
$_SERVER['HTTP_HOST'] = $http_host;
// Declare custom_url_rewrite_outbound()
function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
global $rewrite_prefix;
$path = "~{$rewrite_prefix}/{$path}";
}
}
?>
I've gone over this in my head trying to see if there's some security issues here, but as far as I can tell, it's kosher. Let me know if you think otherwise.
(If you want to be bored by the reason, here it is; We wanted example.net (and other domains) to be accessible over an HTTPS connection, but don't want to buy an SSL certificate for each domain name. This way we can buy one just for example.com and serve all sites, including Drupal ones, through a certified HTTPS connection through that domain.)