| OLD | NEW |
| 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 logging | 5 import logging |
| 6 import posixpath | 6 import posixpath |
| 7 import traceback | 7 import traceback |
| 8 | 8 |
| 9 from branch_utility import BranchUtility | 9 from branch_utility import BranchUtility |
| 10 from environment import IsPreviewServer | 10 from environment import IsPreviewServer |
| 11 from file_system import FileNotFoundError | 11 from file_system import FileNotFoundError |
| 12 from redirector import Redirector | 12 from redirector import Redirector |
| 13 from servlet import Servlet, Response | 13 from servlet import Servlet, Response |
| 14 from special_paths import SITE_VERIFICATION_FILE |
| 14 from third_party.handlebar import Handlebar | 15 from third_party.handlebar import Handlebar |
| 15 | 16 |
| 16 | 17 |
| 17 def _MakeHeaders(content_type): | 18 def _MakeHeaders(content_type): |
| 18 return { | 19 return { |
| 19 'X-Frame-Options': 'sameorigin', | 20 'X-Frame-Options': 'sameorigin', |
| 20 'Content-Type': content_type, | 21 'Content-Type': content_type, |
| 21 'Cache-Control': 'max-age=300', | 22 'Cache-Control': 'max-age=300', |
| 22 } | 23 } |
| 23 | 24 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 52 except FileNotFoundError: | 53 except FileNotFoundError: |
| 53 # Find the closest 404.html file and serve that, e.g. if the path is | 54 # Find the closest 404.html file and serve that, e.g. if the path is |
| 54 # extensions/manifest/typo.html then first look for | 55 # extensions/manifest/typo.html then first look for |
| 55 # extensions/manifest/404.html, then extensions/404.html, then 404.html. | 56 # extensions/manifest/404.html, then extensions/404.html, then 404.html. |
| 56 # | 57 # |
| 57 # Failing that just print 'Not Found' but that should preferrably never | 58 # Failing that just print 'Not Found' but that should preferrably never |
| 58 # happen, because it would look really bad. | 59 # happen, because it would look really bad. |
| 59 path_components = path.split('/') | 60 path_components = path.split('/') |
| 60 for i in xrange(len(path_components) - 1, -1, -1): | 61 for i in xrange(len(path_components) - 1, -1, -1): |
| 61 try: | 62 try: |
| 62 path_404 = posixpath.join(*(path_components[0:i] + ['404.html'])) | 63 path_404 = posixpath.join(*(path_components[0:i] + ['404'])) |
| 63 response = self._GetSuccessResponse(path_404, server_instance) | 64 response = self._GetSuccessResponse(path_404, server_instance) |
| 64 if response.status != 200: | 65 if response.status != 200: |
| 65 continue | 66 continue |
| 66 return Response.NotFound(response.content.ToString(), | 67 return Response.NotFound(response.content.ToString(), |
| 67 headers=response.headers) | 68 headers=response.headers) |
| 68 except FileNotFoundError: continue | 69 except FileNotFoundError: continue |
| 69 logging.warning('No 404.html found in %s' % path) | 70 logging.warning('No 404.html found in %s' % path) |
| 70 return Response.NotFound('Not Found', headers=_MakeHeaders('text/plain')) | 71 return Response.NotFound('Not Found', headers=_MakeHeaders('text/plain')) |
| 71 | 72 |
| 72 def _GetSuccessResponse(self, path, server_instance): | 73 def _GetSuccessResponse(self, path, server_instance): |
| 73 '''Returns the Response from trying to render |path| with | 74 '''Returns the Response from trying to render |path| with |
| 74 |server_instance|. If |path| isn't found then a FileNotFoundError will be | 75 |server_instance|. If |path| isn't found then a FileNotFoundError will be |
| 75 raised, such that the only responses that will be returned from this method | 76 raised, such that the only responses that will be returned from this method |
| 76 are Ok and Redirect. | 77 are Ok and Redirect. |
| 77 ''' | 78 ''' |
| 78 content_provider, path = ( | 79 content_provider, serve_from, path = ( |
| 79 server_instance.content_providers.GetByServeFrom(path)) | 80 server_instance.content_providers.GetByServeFrom(path)) |
| 80 assert content_provider, 'No ContentProvider found for %s' % path | 81 assert content_provider, 'No ContentProvider found for %s' % path |
| 81 | 82 |
| 82 redirect = Redirector( | 83 redirect = Redirector( |
| 83 server_instance.compiled_fs_factory, | 84 server_instance.compiled_fs_factory, |
| 84 content_provider.file_system).Redirect(self._request.host, path) | 85 content_provider.file_system).Redirect(self._request.host, path) |
| 85 if redirect is not None: | 86 if redirect is not None: |
| 86 return Response.Redirect(redirect, permanent=False) | 87 return Response.Redirect(redirect, permanent=False) |
| 87 | 88 |
| 88 canonical_path = content_provider.GetCanonicalPath(path) | 89 canonical_path = content_provider.GetCanonicalPath(path) |
| 89 if canonical_path != path: | 90 if canonical_path != path: |
| 90 return Response.Redirect('/' + canonical_path, permanent=False) | 91 redirect_path = posixpath.join(serve_from, canonical_path) |
| 92 return Response.Redirect('/' + redirect_path, permanent=False) |
| 91 | 93 |
| 92 content_and_type = content_provider.GetContentAndType(path).Get() | 94 content_and_type = content_provider.GetContentAndType(path).Get() |
| 93 if not content_and_type.content: | 95 if not content_and_type.content: |
| 94 logging.error('%s had empty content' % path) | 96 logging.error('%s had empty content' % path) |
| 95 | 97 |
| 96 content = content_and_type.content | 98 content = content_and_type.content |
| 97 if isinstance(content, Handlebar): | 99 if isinstance(content, Handlebar): |
| 98 template_content, template_warnings = ( | 100 template_content, template_warnings = ( |
| 99 server_instance.template_renderer.Render(content, self._request)) | 101 server_instance.template_renderer.Render(content, self._request)) |
| 100 # HACK: the Google ID thing (google2ed...) doesn't have a title. | 102 # HACK: the site verification file (google2ed...) doesn't have a title. |
| 101 content, doc_warnings = server_instance.document_renderer.Render( | 103 content, doc_warnings = server_instance.document_renderer.Render( |
| 102 template_content, | 104 template_content, |
| 103 path, | 105 path, |
| 104 render_title=path != 'google2ed1af765c529f57.html') | 106 render_title=path != SITE_VERIFICATION_FILE) |
| 105 warnings = template_warnings + doc_warnings | 107 warnings = template_warnings + doc_warnings |
| 106 if warnings: | 108 if warnings: |
| 107 sep = '\n - ' | 109 sep = '\n - ' |
| 108 logging.warning('Rendering %s:%s%s' % (path, sep, sep.join(warnings))) | 110 logging.warning('Rendering %s:%s%s' % (path, sep, sep.join(warnings))) |
| 109 | 111 |
| 110 content_type = content_and_type.content_type | 112 content_type = content_and_type.content_type |
| 111 if isinstance(content, unicode): | 113 if isinstance(content, unicode): |
| 112 content = content.encode('utf-8') | 114 content = content.encode('utf-8') |
| 113 content_type += '; charset=utf-8' | 115 content_type += '; charset=utf-8' |
| 114 | 116 |
| 115 return Response.Ok(content, headers=_MakeHeaders(content_type)) | 117 return Response.Ok(content, headers=_MakeHeaders(content_type)) |
| OLD | NEW |