Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: chrome/common/extensions/docs/server2/render_servlet.py

Issue 14856006: Docserver: achieve online vs offline (cron vs instance) behaviour at the object (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from fnmatch import fnmatch 5 from fnmatch import fnmatch
6 import logging 6 import logging
7 import mimetypes 7 import mimetypes
8 import os 8 import os
9 import traceback 9 import traceback
10 10
11 from appengine_wrappers import IsDevServer 11 from appengine_wrappers import IsDevServer
12 from branch_utility import BranchUtility 12 from branch_utility import BranchUtility
13 from file_system import FileNotFoundError 13 from file_system import FileNotFoundError
14 from server_instance import ServerInstance 14 from server_instance import ServerInstance
15 from servlet import Servlet, Response 15 from servlet import Servlet, Response
16 import svn_constants 16 import svn_constants
17 from third_party.json_schema_compiler.memoize import memoize
17 18
18 _DEFAULT_CHANNEL = 'stable' 19 _DEFAULT_CHANNEL = 'stable'
19 20
20 _ALWAYS_ONLINE = IsDevServer() 21 _ALWAYS_ONLINE = IsDevServer()
21 22
22 def _IsBinaryMimetype(mimetype): 23 def _IsBinaryMimetype(mimetype):
23 return any(mimetype.startswith(prefix) 24 return any(mimetype.startswith(prefix)
24 for prefix in ['audio', 'image', 'video']) 25 for prefix in ['audio', 'image', 'video'])
25 26
26 def AlwaysOnline(fn): 27 @memoize
27 '''A function decorator which forces the rendering to be always online rather 28 def _GetOrCreateServerInstance(channel):
28 than the default offline behaviour. Useful for testing. 29 return ServerInstance.CreateOffline(channel)
29 '''
30 def impl(*args, **optargs):
31 global _ALWAYS_ONLINE
32 was_always_online = _ALWAYS_ONLINE
33 try:
34 _ALWAYS_ONLINE = True
35 return fn(*args, **optargs)
36 finally:
37 _ALWAYS_ONLINE = was_always_online
38 return impl
39 30
40 class RenderServlet(Servlet): 31 class RenderServlet(Servlet):
41 '''Servlet which renders templates. 32 '''Servlet which renders templates.
42 ''' 33 '''
43 def Get(self, server_instance=None): 34 def Get(self, server_instance=None):
35 # A note about |server_instance|:
36 #
37 # AppEngine instances should never need to call out to SVN. That should
38 # only ever be done by the cronjobs, which then write the result into
39 # DataStore, which is as far as instances look. To enable this, crons can
40 # pass a custom (presumably online) ServerInstance into Get().
41 #
42 # Why? SVN is slow and a bit flaky. Cronjobs failing is annoying but
43 # temporary. Instances failing affects users, and is really bad.
44 #
45 # Anyway - to enforce this, we actually don't give instances access to SVN.
46 # If anything is missing from datastore, it'll be a 404. If the cronjobs
47 # don't manage to catch everything - uhoh. On the other hand, we'll figure
48 # it out pretty soon, and it also means that legitimate 404s are caught
49 # before a round trip to SVN.
50
44 path_with_channel, headers = (self._request.path.lstrip('/'), 51 path_with_channel, headers = (self._request.path.lstrip('/'),
45 self._request.headers) 52 self._request.headers)
46 53
47 # Redirect "extensions" and "extensions/" to "extensions/index.html", etc. 54 # Redirect "extensions" and "extensions/" to "extensions/index.html", etc.
48 if (os.path.splitext(path_with_channel)[1] == '' and 55 if (os.path.splitext(path_with_channel)[1] == '' and
49 path_with_channel.find('/') == -1): 56 path_with_channel.find('/') == -1):
50 path_with_channel += '/' 57 path_with_channel += '/'
51 if path_with_channel.endswith('/'): 58 if path_with_channel.endswith('/'):
52 return Response.Redirect(path_with_channel + 'index.html') 59 return Response.Redirect(path_with_channel + 'index.html')
53 60
54 channel, path = BranchUtility.SplitChannelNameFromPath(path_with_channel) 61 channel, path = BranchUtility.SplitChannelNameFromPath(path_with_channel)
55 62
56 if channel == _DEFAULT_CHANNEL: 63 if channel == _DEFAULT_CHANNEL:
57 return Response.Redirect('/%s' % path) 64 return Response.Redirect('/%s' % path)
58 65
59 if channel is None: 66 if channel is None:
60 channel = _DEFAULT_CHANNEL 67 channel = _DEFAULT_CHANNEL
61 68
62 # AppEngine instances should never need to call out to SVN. That should
63 # only ever be done by the cronjobs, which then write the result into
64 # DataStore, which is as far as instances look. To enable this, crons can
65 # pass a custom (presumably online) ServerInstance into Get().
66 #
67 # Why? SVN is slow and a bit flaky. Cronjobs failing is annoying but
68 # temporary. Instances failing affects users, and is really bad.
69 #
70 # Anyway - to enforce this, we actually don't give instances access to SVN.
71 # If anything is missing from datastore, it'll be a 404. If the cronjobs
72 # don't manage to catch everything - uhoh. On the other hand, we'll figure
73 # it out pretty soon, and it also means that legitimate 404s are caught
74 # before a round trip to SVN.
75 if server_instance is None: 69 if server_instance is None:
76 # The ALWAYS_ONLINE thing is for tests and preview.py that shouldn't need 70 server_instance = _GetOrCreateServerInstance(channel)
77 # to run the cron before rendering things.
78 constructor = (ServerInstance.CreateOnline if _ALWAYS_ONLINE else
79 ServerInstance.GetOrCreateOffline)
80 server_instance = constructor(channel)
81 71
82 canonical_path = server_instance.path_canonicalizer.Canonicalize(path) 72 canonical_path = server_instance.path_canonicalizer.Canonicalize(path)
83 if path != canonical_path: 73 if path != canonical_path:
84 return Response.Redirect(canonical_path if channel is None else 74 return Response.Redirect(canonical_path if channel is None else
85 '%s/%s' % (channel, canonical_path)) 75 '%s/%s' % (channel, canonical_path))
86 76
87 templates = server_instance.template_data_source_factory.Create( 77 templates = server_instance.template_data_source_factory.Create(
88 self._request, path) 78 self._request, path)
89 79
90 content = None 80 content = None
(...skipping 28 matching lines...) Expand all
119 return Response.NotFound(templates.Render('404'), headers=headers) 109 return Response.NotFound(templates.Render('404'), headers=headers)
120 110
121 if not content: 111 if not content:
122 logging.error('%s had empty content' % path) 112 logging.error('%s had empty content' % path)
123 113
124 headers.update({ 114 headers.update({
125 'content-type': content_type, 115 'content-type': content_type,
126 'cache-control': 'max-age=300', 116 'cache-control': 'max-age=300',
127 }) 117 })
128 return Response.Ok(content, headers=headers) 118 return Response.Ok(content, headers=headers)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698