1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
6 from urlparse import urlsplit
8 from file_system import FileNotFoundError
9 from future import Future
11 class Redirector(object):
12 def __init__(self, compiled_fs_factory, file_system):
13 self._file_system = file_system
14 self._cache = compiled_fs_factory.ForJson(file_system)
16 def Redirect(self, host, path):
17 ''' Check if a path should be redirected, first according to host
18 redirection rules, then from rules in redirects.json files.
20 Returns the path that should be redirected to, or None if no redirection
23 return self._RedirectOldHosts(host, path) or self._RedirectFromConfig(path)
25 def _RedirectFromConfig(self, url):
26 ''' Lookup the redirects configuration file in the directory that contains
27 the requested resource. If no redirection rule is matched, or no
28 configuration file exists, returns None.
30 dirname, filename = posixpath.split(url)
33 rules = self._cache.GetFromFile(
34 posixpath.join(dirname, 'redirects.json')).Get()
35 except FileNotFoundError:
38 redirect = rules.get(filename)
41 if (redirect.startswith('/') or
42 urlsplit(redirect).scheme in ('http', 'https')):
45 return posixpath.normpath(posixpath.join(dirname, redirect))
47 def _RedirectOldHosts(self, host, path):
48 ''' Redirect paths from the old code.google.com to the new
49 developer.chrome.com, retaining elements like the channel and https, if
52 if urlsplit(host).hostname != 'code.google.com':
55 path = path.split('/')
56 if path and path[0] == 'chrome':
59 return 'https://developer.chrome.com/' + posixpath.join(*path)
62 ''' Load files during a cron run.
65 for root, dirs, files in self._file_system.Walk(''):
66 if 'redirects.json' in files:
68 self._cache.GetFromFile(posixpath.join(root, 'redirects.json')))
69 return Future(callback=lambda: [f.Get() for f in futures])