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

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

Issue 15087006: Docserver: there is only one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: better redirects 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
13 from file_system import FileNotFoundError 12 from file_system import FileNotFoundError
14 from server_instance import ServerInstance 13 from server_instance import ServerInstance
15 from servlet import Servlet, Response 14 from servlet import Servlet, Response
16 import svn_constants 15 import svn_constants
17 16
18 def _IsBinaryMimetype(mimetype): 17 def _IsBinaryMimetype(mimetype):
19 return any(mimetype.startswith(prefix) 18 return any(mimetype.startswith(prefix)
20 for prefix in ['audio', 'image', 'video']) 19 for prefix in ['audio', 'image', 'video'])
21 20
22 class RenderServlet(Servlet): 21 class RenderServlet(Servlet):
23 '''Servlet which renders templates. 22 '''Servlet which renders templates.
24 ''' 23 '''
25 class Delegate(object): 24 class Delegate(object):
26 def CreateServerInstanceForChannel(self, channel): 25 def CreateServerInstance(self):
27 raise NotImplementedError() 26 raise NotImplementedError(self.__class__)
28 27
29 def __init__(self, request, delegate, default_channel='stable'): 28 def __init__(self, request, delegate):
30 Servlet.__init__(self, request) 29 Servlet.__init__(self, request)
31 self._delegate = delegate 30 self._delegate = delegate
32 self._default_channel = default_channel
33 31
34 def Get(self): 32 def Get(self):
35 path_with_channel, headers = (self._request.path, self._request.headers) 33 server_instance = self._delegate.CreateServerInstance()
36 34
37 # Redirect "extensions" and "extensions/" to "extensions/index.html", etc. 35 path = self._request.path
38 if (os.path.splitext(path_with_channel)[1] == '' and 36 canonical_result = server_instance.path_canonicalizer.Canonicalize(path)
cduvall 2013/05/15 00:50:50 does the path passed in here have a leading '/'? I
not at google - send to devlin 2013/05/15 01:26:50 yeah, the servlet strips off the leading '/' for t
39 path_with_channel.find('/') == -1): 37 canonical_path = canonical_result.path.lstrip('/')
40 path_with_channel += '/' 38 # TODO(kalman): do this generically by detecting index.html.
41 if path_with_channel.endswith('/'): 39 if canonical_path in ('apps/', 'extensions/'):
42 return Response.Redirect('/%sindex.html' % path_with_channel) 40 canonical_path += 'index.html'
43
44 channel, path = BranchUtility.SplitChannelNameFromPath(path_with_channel)
45
46 if channel == self._default_channel:
47 return Response.Redirect('/%s' % path)
48
49 if channel is None:
50 channel = self._default_channel
51
52 server_instance = self._delegate.CreateServerInstanceForChannel(channel)
53
54 canonical_path = (
55 server_instance.path_canonicalizer.Canonicalize(path).lstrip('/'))
56 if path != canonical_path: 41 if path != canonical_path:
57 redirect_path = (canonical_path if channel is None else 42 return Response.Redirect('/%s' % canonical_path,
58 '%s/%s' % (channel, canonical_path)) 43 permanent=canonical_result.permanent)
59 return Response.Redirect('/%s' % redirect_path)
60 44
61 templates = server_instance.template_data_source_factory.Create( 45 templates = server_instance.template_data_source_factory.Create(
62 self._request, path) 46 self._request, path)
63 47
64 content = None 48 content = None
65 content_type = None 49 content_type = None
66 50
67 try: 51 try:
68 if fnmatch(path, 'extensions/examples/*.zip'): 52 if fnmatch(path, 'extensions/examples/*.zip'):
69 content = server_instance.example_zipper.Create( 53 content = server_instance.example_zipper.Create(
(...skipping 23 matching lines...) Expand all
93 return Response.NotFound(templates.Render('404'), headers=headers) 77 return Response.NotFound(templates.Render('404'), headers=headers)
94 78
95 if not content: 79 if not content:
96 logging.error('%s had empty content' % path) 80 logging.error('%s had empty content' % path)
97 81
98 headers.update({ 82 headers.update({
99 'content-type': content_type, 83 'content-type': content_type,
100 'cache-control': 'max-age=300', 84 'cache-control': 'max-age=300',
101 }) 85 })
102 return Response.Ok(content, headers=headers) 86 return Response.Ok(content, headers=headers)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698