blob: 9c8136ea0d9cce43c3adfbf0f7161fa61f941e86 [file] [log] [blame]
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import posixpath
from urlparse import urlsplit
from file_system import FileNotFoundError
from third_party.json_schema_compiler.json_parse import Parse
class Redirector(object):
def __init__(self, compiled_fs_factory, file_system, root_path):
self._root_path = root_path
self._file_system = file_system
self._cache = compiled_fs_factory.Create(
file_system, lambda _, rules: Parse(rules), Redirector)
def Redirect(self, host, path):
''' Check if a path should be redirected, first according to host
redirection rules, then from rules in redirects.json files.
Returns the path that should be redirected to, or None if no redirection
should occur.
'''
return self._RedirectOldHosts(host, path) or self._RedirectFromConfig(path)
def _RedirectFromConfig(self, url):
''' Lookup the redirects configuration file in the directory that contains
the requested resource. If no redirection rule is matched, or no
configuration file exists, returns None.
'''
dirname, filename = posixpath.split(url)
try:
rules = self._cache.GetFromFile(
posixpath.join(self._root_path, dirname, 'redirects.json')).Get()
except FileNotFoundError:
return None
redirect = rules.get(filename)
if redirect is None:
return None
if (redirect.startswith('/') or
urlsplit(redirect).scheme in ('http', 'https')):
return redirect
return posixpath.normpath('/' + posixpath.join(dirname, redirect))
def _RedirectOldHosts(self, host, path):
''' Redirect paths from the old code.google.com to the new
developer.chrome.com, retaining elements like the channel and https, if
used.
'''
if urlsplit(host).hostname != 'code.google.com':
return None
path = path.split('/')
if path and path[0] == 'chrome':
path.pop(0)
return 'https://developer.chrome.com/' + posixpath.join(*path)
def Cron(self):
''' Load files during a cron run.
'''
for root, dirs, files in self._file_system.Walk(self._root_path):
if 'redirects.json' in files:
self._cache.GetFromFile('%s/redirects.json' % posixpath.join(
self._root_path, root).rstrip('/')).Get()