cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / patch_servlet.py
blob1dfb4d7f0e3aca69590068371766ee7a70d5a860
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.
5 from fnmatch import fnmatch
6 import logging
8 from caching_rietveld_patcher import CachingRietveldPatcher
9 from chained_compiled_file_system import ChainedCompiledFileSystem
10 from environment import IsDevServer
11 from environment_wrappers import CreateUrlFetcher
12 from extensions_paths import CONTENT_PROVIDERS
13 from instance_servlet import InstanceServlet
14 from render_servlet import RenderServlet
15 from rietveld_patcher import RietveldPatcher, RietveldPatcherError
16 from object_store_creator import ObjectStoreCreator
17 from patched_file_system import PatchedFileSystem
18 from server_instance import ServerInstance
19 from servlet import Request, Response, Servlet
20 import url_constants
21 from gcs_file_system_provider import CloudStorageFileSystemProvider
24 class _PatchServletDelegate(RenderServlet.Delegate):
25 def __init__(self, issue, delegate):
26 self._issue = issue
27 self._delegate = delegate
29 def CreateServerInstance(self):
30 # start_empty=False because a patch can rely on files that are already in
31 # the Git repository but not yet pulled into data store by cron jobs (a
32 # typical example is to add documentation for an existing API).
33 object_store_creator = ObjectStoreCreator(start_empty=False)
35 unpatched_file_system = self._delegate.CreateHostFileSystemProvider(
36 object_store_creator).GetMaster()
38 rietveld_patcher = CachingRietveldPatcher(
39 RietveldPatcher(self._issue,
40 CreateUrlFetcher(url_constants.CODEREVIEW_SERVER)),
41 object_store_creator)
43 patched_file_system = PatchedFileSystem(unpatched_file_system,
44 rietveld_patcher)
46 patched_host_file_system_provider = (
47 self._delegate.CreateHostFileSystemProvider(
48 object_store_creator,
49 # The patched file system needs to be online otherwise it'd be
50 # impossible to add files in the patches.
51 offline=False,
52 # The master file system for this creator should be the patched one.
53 default_master_instance=patched_file_system))
55 combined_compiled_fs_factory = ChainedCompiledFileSystem.Factory(
56 [unpatched_file_system], object_store_creator)
58 branch_utility = self._delegate.CreateBranchUtility(object_store_creator)
60 server_instance = ServerInstance(
61 object_store_creator,
62 combined_compiled_fs_factory,
63 branch_utility,
64 patched_host_file_system_provider,
65 CloudStorageFileSystemProvider(object_store_creator),
66 base_path='/_patch/%s/' % self._issue)
68 # HACK: if content_providers.json changes in this patch then the cron needs
69 # to be re-run to pull in the new configuration.
70 _, _, modified = rietveld_patcher.GetPatchedFiles()
71 if CONTENT_PROVIDERS in modified:
72 server_instance.content_providers.Refresh().Get()
74 return server_instance
76 class PatchServlet(Servlet):
77 '''Servlet which renders patched docs.
78 '''
79 def __init__(self, request, delegate=None):
80 self._request = request
81 self._delegate = delegate or InstanceServlet.Delegate()
83 def Get(self):
84 if (not IsDevServer() and
85 not fnmatch(self._request.host, '*.appspot.com')):
86 # Only allow patches on appspot URLs; it doesn't matter if appspot.com is
87 # XSS'ed, but it matters for chrome.com.
88 redirect_host = 'chrome-apps-doc.appspot.com'
89 logging.info('Redirecting from XSS-able host %s to %s' % (
90 self._request.host, redirect_host))
91 return Response.Redirect(
92 'https://%s/_patch/%s' % (redirect_host, self._request.path))
94 path_with_issue = self._request.path.lstrip('/')
95 if '/' in path_with_issue:
96 issue, path_without_issue = path_with_issue.split('/', 1)
97 else:
98 return Response.NotFound('Malformed URL. It should look like ' +
99 'https://developer.chrome.com/_patch/12345/extensions/...')
101 try:
102 response = RenderServlet(
103 Request(path_without_issue,
104 self._request.host,
105 self._request.headers),
106 _PatchServletDelegate(issue, self._delegate)).Get()
107 # Disable cache for patched content.
108 response.headers.pop('cache-control', None)
109 except RietveldPatcherError as e:
110 response = Response.NotFound(e.message, {'Content-Type': 'text/plain'})
112 redirect_url, permanent = response.GetRedirect()
113 if redirect_url is not None:
114 response = Response.Redirect('/_patch/%s%s' % (issue, redirect_url),
115 permanent)
116 return response