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

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

Issue 218363002: Docs: Use ETags. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 8 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 import hashlib
5 import logging 6 import logging
6 import posixpath 7 import posixpath
7 import traceback 8 import traceback
8 9
9 from branch_utility import BranchUtility 10 from branch_utility import BranchUtility
10 from environment import IsPreviewServer 11 from environment import IsPreviewServer
11 from file_system import FileNotFoundError 12 from file_system import FileNotFoundError
12 from redirector import Redirector 13 from redirector import Redirector
13 from servlet import Servlet, Response 14 from servlet import Servlet, Response
14 from special_paths import SITE_VERIFICATION_FILE 15 from special_paths import SITE_VERIFICATION_FILE
15 from third_party.handlebar import Handlebar 16 from third_party.handlebar import Handlebar
16 17
17 18
18 def _MakeHeaders(content_type): 19 def _MakeHeaders(content_type, etag=None):
19 return { 20 headers = {
21 # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1.
22 'Cache-Control': 'public, max-age=0, no-cache',
23 'Content-Type': content_type,
20 'X-Frame-Options': 'sameorigin', 24 'X-Frame-Options': 'sameorigin',
21 'Content-Type': content_type,
22 'Cache-Control': 'max-age=300',
23 } 25 }
26 if etag is not None:
27 headers['ETag'] = etag
28 return headers
24 29
25 30
26 class RenderServlet(Servlet): 31 class RenderServlet(Servlet):
27 '''Servlet which renders templates. 32 '''Servlet which renders templates.
28 ''' 33 '''
29 34
30 class Delegate(object): 35 class Delegate(object):
31 def CreateServerInstance(self): 36 def CreateServerInstance(self):
32 raise NotImplementedError(self.__class__) 37 raise NotImplementedError(self.__class__)
33 38
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 server_instance.template_renderer.Render(content, self._request)) 120 server_instance.template_renderer.Render(content, self._request))
116 # HACK: the site verification file (google2ed...) doesn't have a title. 121 # HACK: the site verification file (google2ed...) doesn't have a title.
117 content, doc_warnings = server_instance.document_renderer.Render( 122 content, doc_warnings = server_instance.document_renderer.Render(
118 template_content, 123 template_content,
119 path, 124 path,
120 render_title=path != SITE_VERIFICATION_FILE) 125 render_title=path != SITE_VERIFICATION_FILE)
121 warnings = template_warnings + doc_warnings 126 warnings = template_warnings + doc_warnings
122 if warnings: 127 if warnings:
123 sep = '\n - ' 128 sep = '\n - '
124 logging.warning('Rendering %s:%s%s' % (path, sep, sep.join(warnings))) 129 logging.warning('Rendering %s:%s%s' % (path, sep, sep.join(warnings)))
130 # Content was dynamic. The new etag is a hash of the content.
131 etag = None
132 elif content_and_type.version is not None:
133 # Content was static. The new etag is the version of the content.
134 etag = '"%s"' % content_and_type.version
135 else:
136 # Sometimes non-dynamic content does not have a version, for example
137 # .zip files. The new etag is a hash of the content.
138 etag = None
125 139
126 content_type = content_and_type.content_type 140 content_type = content_and_type.content_type
127 if isinstance(content, unicode): 141 if isinstance(content, unicode):
128 content = content.encode('utf-8') 142 content = content.encode('utf-8')
129 content_type += '; charset=utf-8' 143 content_type += '; charset=utf-8'
130 144
131 return Response.Ok(content, headers=_MakeHeaders(content_type)) 145 if etag is None:
146 # Note: we're using md5 as a convenient and fast-enough way to identify
147 # content. It's not intended to be cryptographic in any way, and this
148 # is *not* what etags is for. That's what SSL is for, this is unrelated.
149 etag = '"%s"' % hashlib.md5(content).hexdigest()
150
151 headers = _MakeHeaders(content_type, etag=etag)
152 if etag == self._request.headers.get('If-None-Match'):
153 return Response.NotModified('Not Modified', headers=headers)
154 return Response.Ok(content, headers=headers)
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/server2/preview.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