0

We are in the process of migrating a Drupal site to Pantheon. The site uses about 55 rewrites and redirects rules in its pre-migration NGINX configuration. Most of them (32) include widlcards (eg. ^/something/(.*) redirects to /something-else/) and an handful even keep the matching substring into the redirect-to URL (eg. ^/another/one/(.*)$ redirects to /something/else/$1).

Pantheon does not support redirects at the web-server levels and suggests doing redirects in the settings.php (to avoid boostraping Drupal). But 55 redirects seems enough to start worry about maintainability of a bunch of if blocks. There is also the performance cost of 32 pattern matching for each request. So a little care has to be taken to avoid maintenance nightmare in the future.

I'm not too worried about performances since the site is mostly cached anonymous traffic. But in addition to requiring a full bootstrap, the Redirect module (already used on the site) is not an option as it does not support wildcards.

I'm toying with the idea of crafting something with nikic/FastRoute to be used from settings.php. But this seems a bit overkill for 55 redirects.

I'm curious what options have been used on other sites with similar requirements.

  • 1
    Please note that the answers below are about redirects, not rewrites. These are very different things and the question is misleading in that it assumes the two are interchangeable or synonymous. – cdonner May 22 '17 at 18:32
1

If you have a reverse proxy service/server sitting in front of your Pantheon instance, it seems like that's the place to place your redirect rules. Rewriting/redirection is a common feature of reverse proxies.

For example, CloudFlare supports redirect patterns under its Page Rules manager. Pantheon has a few doc pages that bring up using CloudFlare so it looks to be a common configure they see used with their service.

If you have a Varnish instance in front your Pantheon instance, you can configure rewrite/redirects in VCL.

  • We are using Fastly as CDN, and the redirects could have been done with custom VCL and maybe though their config UI. This would have required an additional step in the deployment process. Redirects in settings.php have the benefit of being deployed and tested with the rest of the code. – Pierre Buyle Oct 5 '16 at 13:49
1

Turns out a solution based on nikic/fast-route is quite simple. The actual code is about 30 LoC (not counting the redirections rules themselves):

$redirects = [
 'something/{anything:.*}' => 'something-else/{anything}',
 'another/one/{anything:.*}' => 'something/else/{anything}',
]
doDedirects($redirects);
function doDedirects($redirects) {
  // Collect redirects routes
  $dispatcher = FastRoute\cachedDispatcher(function(FastRoute\RouteCollector $r) use ($redirects) {
    foreach ($redirects as $source => $destination) {
      $r->addRoute('GET', $source, $destination);
    }
  }, [
    'cacheFile' => sys_get_temp_dir()  . '/route.cache',
    'cacheDisabled' => FALSE,     /* optional, enabled by default */
  ]);
  // Fetch method and URI from somewhere
  if (!empty($_SERVER['REQUEST_METHOD']) && !empty($_SERVER['REQUEST_URI'])) {
    $httpMethod = $_SERVER['REQUEST_METHOD'];
    $uri = rawurldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));

    // Match method and URI with redirection rules.
    $routeInfo = $dispatcher->dispatch($httpMethod, $uri);
    if ($routeInfo[0] == FastRoute\Dispatcher::FOUND) {
      $replace = [];
      foreach ($routeInfo[2] as $key => $value) {
        $replace["{{$key}}"] = $value;
      }
      $dest = strtr($routeInfo[1], $replace);
      header("HTTP/1.1 301 Moved Permanently");
      header("Location: $dest");
      die();
    }
  }
}

This is likely a bit overkill as performances is not really a concern. I went with this solution for its simplicity. The code is quite simple and probably as readable/maintainable as a simple solution that would iterate over an array of regular expressions. FastRoute is supposed to scale pretty well, so I assume this solution would scale pretty well too.

Note: The Match Redirect module has been suggested too. It would have been a good solution if it had support for using the wildcards' values in the destination.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.