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

Unified Diff: chrome/common/extensions/docs/server2/render_servlet.py

Issue 54603010: Docserver: Implement the content providers infrastructure, where a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/server2/render_servlet.py
diff --git a/chrome/common/extensions/docs/server2/render_servlet.py b/chrome/common/extensions/docs/server2/render_servlet.py
index 25b6d3ded6c869c0d5778e87beb888d559412c24..cb0c4dcf49f1a751b1a7ebd1b7449c80d97e1e72 100644
--- a/chrome/common/extensions/docs/server2/render_servlet.py
+++ b/chrome/common/extensions/docs/server2/render_servlet.py
@@ -5,20 +5,30 @@
from fnmatch import fnmatch
import logging
import mimetypes
+import posixpath
+import traceback
from urlparse import urlsplit
from data_source_registry import CreateDataSources
from file_system import FileNotFoundError
+from redirector import Redirector
from servlet import Servlet, Response
from svn_constants import DOCS_PATH, PUBLIC_TEMPLATE_PATH
+from third_party.handlebar import Handlebar
+
+
+def _MakeHeaders(content_type):
+ return {
+ 'x-frame-options': 'sameorigin',
+ 'content-type': content_type,
+ 'cache-control': 'max-age=300',
+ }
-def _IsBinaryMimetype(mimetype):
- return any(
- mimetype.startswith(prefix) for prefix in ['audio', 'image', 'video'])
class RenderServlet(Servlet):
'''Servlet which renders templates.
'''
+
class Delegate(object):
def CreateServerInstance(self):
raise NotImplementedError(self.__class__)
@@ -33,82 +43,61 @@ class RenderServlet(Servlet):
# TODO(kalman): a consistent path syntax (even a Path class?) so that we
# can stop being so conservative with stripping and adding back the '/'s.
path = self._request.path.lstrip('/')
-
- if path.split('/')[-1] == 'redirects.json':
- return Response.Ok('')
-
server_instance = self._delegate.CreateServerInstance()
- redirect = server_instance.redirector.Redirect(self._request.host, path)
- if redirect is not None:
- return Response.Redirect(redirect)
-
- canonical_result = server_instance.path_canonicalizer.Canonicalize(path)
- redirect = canonical_result.path.lstrip('/')
- if path != redirect:
- return Response.Redirect('/' + redirect,
- permanent=canonical_result.permanent)
-
- trunk_fs = server_instance.host_file_system_provider.GetTrunk()
- template_renderer = server_instance.template_renderer
- template_cache = server_instance.compiled_fs_factory.ForTemplates(trunk_fs)
-
- content = None
- content_type = None
-
try:
- # At this point, any valid paths ending with '/' have been redirected.
- # Therefore, the response should be a 404 Not Found.
- if path.endswith('/'):
- pass
- elif fnmatch(path, 'extensions/examples/*.zip'):
- zip_path = DOCS_PATH + path[len('extensions'):-len('.zip')]
- content = server_instance.directory_zipper.Zip(zip_path).Get()
- content_type = 'application/zip'
- elif path.startswith('extensions/examples/'):
- mimetype = mimetypes.guess_type(path)[0] or 'text/plain'
- content = trunk_fs.ReadSingle(
- '%s/%s' % (DOCS_PATH, path[len('extensions/'):]),
- binary=_IsBinaryMimetype(mimetype)).Get()
- content_type = mimetype
- elif path.startswith('static/'):
- mimetype = mimetypes.guess_type(path)[0] or 'text/plain'
- content = trunk_fs.ReadSingle(
- '%s/%s' % (DOCS_PATH, path),
- binary=_IsBinaryMimetype(mimetype)).Get()
- content_type = mimetype
- elif path.endswith('.html'):
- content = template_renderer.Render(
- template_cache.GetFromFile(
- '%s/%s' % (PUBLIC_TEMPLATE_PATH, path)).Get(),
- self._request)
- content_type = 'text/html'
- else:
- content = None
+ return self._GetSuccessResponse(path, server_instance)
except FileNotFoundError:
- content = None
-
- headers = {'x-frame-options': 'sameorigin'}
- if content is None:
- def render_template_or_none(path):
+ # Maybe it didn't find the file because its canonical location is
+ # somewhere else; this is distinct from "redirects", which are typically
+ # explicit. This is implicit.
+ canonical_result = server_instance.path_canonicalizer.Canonicalize(path)
+ redirect = canonical_result.path.lstrip('/')
+ if path != redirect:
+ return Response.Redirect('/' + redirect,
+ permanent=canonical_result.permanent)
+
+ # Not found for reals. Find the closest 404.html file and serve that;
+ # e.g. if the path is extensions/manifest/typo.html then first look for
+ # extensions/manifest/404.html, then extensions/404.html, then 404.html.
+ #
+ # Failing that just print 'Not Found' but that should preferrably never
+ # happen, because it would look really bad.
+ path_components = path.split('/')
+ for i in xrange(len(path_components) - 1, -1, -1):
try:
- return template_renderer.Render(
- template_cache.GetFromFile(
- '%s/%s' % (PUBLIC_TEMPLATE_PATH, path)).Get(),
- self._request)
- except FileNotFoundError:
- return None
- content = (render_template_or_none('%s/404.html' %
- path.split('/', 1)[0]) or
- render_template_or_none('extensions/404.html') or
- 'Not found')
- return Response.NotFound(content, headers=headers)
-
- if not content:
+ path_404 = posixpath.join(*(path_components[0:i] + ['404.html']))
+ response = self._GetSuccessResponse(path_404, server_instance)
+ return Response.NotFound(response.content.ToString(),
+ headers=response.headers)
+ except FileNotFoundError: continue
+ logging.error('No 404.html found in %s' % path)
+ return Response.NotFound('Not Found', headers=_MakeHeaders('text/plain'))
+
+ def _GetSuccessResponse(self, path, server_instance):
+ '''Returns the Response from trying to render |path| with
+ |server_instance|. If |path| isn't found then a FileNotFoundError will be
+ raised, such that the only responses that will be returned from this method
+ are Ok and Redirect.
+ '''
+ content_provider, path = (
+ server_instance.content_providers.GetByServeFrom(path))
+ assert content_provider, 'No ContentProvider found for %s' % path
+
+ redirect = Redirector(
+ server_instance.compiled_fs_factory,
+ content_provider.file_system).Redirect(self._request.host, path)
+ if redirect is not None:
+ return Response.Redirect(redirect, permanent=False)
+
+ content_and_type = content_provider.GetContentAndType(
+ self._request.host, path).Get()
+ if not content_and_type.content:
logging.error('%s had empty content' % path)
- headers.update({
- 'content-type': content_type,
- 'cache-control': 'max-age=300',
- })
- return Response.Ok(content, headers=headers)
+ if isinstance(content_and_type.content, Handlebar):
+ content_and_type.content = server_instance.template_renderer.Render(
+ content_and_type.content, self._request)
+
+ return Response.Ok(content_and_type.content,
+ headers=_MakeHeaders(content_and_type.content_type))
« no previous file with comments | « chrome/common/extensions/docs/server2/redirector_test.py ('k') | chrome/common/extensions/docs/server2/render_servlet_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698