def Get(self): ''' Render the page for a request. ''' path = self._request.path.lstrip('/') # The server used to be partitioned based on Chrome channel, but it isn't # anymore. Redirect from the old state. channel_name, path = BranchUtility.SplitChannelNameFromPath(path) if channel_name is not None: return Response.Redirect('/' + path, permanent=True) server_instance = self._delegate.CreateServerInstance() try: return self._GetSuccessResponse(path, server_instance) except FileNotFoundError: # 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: path_404 = posixpath.join(*(path_components[0:i] + ['404'])) response = self._GetSuccessResponse(path_404, server_instance) if response.status != 200: continue return Response.NotFound(response.content.ToString(), headers=response.headers) except FileNotFoundError: continue logging.warning('No 404.html found in %s' % path) return Response.NotFound('Not Found', headers=_MakeHeaders('text/plain'))
def Get(self): if (not IsDevServer() and not fnmatch( urlparse(self._request.host).netloc, '*.appspot.com')): # Only allow patches on appspot URLs; it doesn't matter if appspot.com is # XSS'ed, but it matters for chrome.com. redirect_host = 'https://chrome-apps-doc.appspot.com' logging.info('Redirecting from XSS-able host %s to %s' % (self._request.host, redirect_host)) return Response.Redirect('%s/_patch/%s' % (redirect_host, self._request.path)) path_with_issue = self._request.path.lstrip('/') if '/' in path_with_issue: issue, path_without_issue = path_with_issue.split('/', 1) else: return Response.NotFound( 'Malformed URL. It should look like ' + 'https://developer.chrome.com/_patch/12345/extensions/...') try: response = RenderServlet( Request(path_without_issue, self._request.host, self._request.headers), _PatchServletDelegate(issue, self._delegate)).Get() # Disable cache for patched content. response.headers.pop('cache-control', None) except RietveldPatcherError as e: response = Response.NotFound(e.message, {'Content-Type': 'text/plain'}) redirect_url, permanent = response.GetRedirect() if redirect_url is not None: response = Response.Redirect( '/_patch/%s%s' % (issue, redirect_url), permanent) return response
def Get(self): link_error_tests = ('broken_links', 'orphaned_pages', 'link_errors') if not self._request.path in link_error_tests: return Response.NotFound( 'Test %s not found. Available tests are: %s' % (self._request.path, ','.join(link_error_tests))) constructor = InstanceServlet.GetConstructor(self._delegate) def renderer(path): return constructor(Request(path, '', self._request.headers)).Get() link_tester = BrokenLinkTester( InstanceServletRenderServletDelegate( self._delegate).CreateServerInstance(), renderer) if self._request.path == 'broken_links': errors, content = link_tester.TestBrokenLinks() elif self._request.path == 'orphaned_pages': errors, content = link_tester.TestOrphanedPages() else: link_errors, link_content = link_tester.TestBrokenLinks() orphaned_errors, orphaned_content = link_tester.TestOrphanedPages() errors = link_errors + orphaned_errors content = "%s\n%s" % (link_content, orphaned_content) if errors: return Response.InternalError(content=content) return Response.Ok(content="%s test passed." % self._request.path)
def Get(self): path = self._request.path redirect = self._RedirectSpecialCases() if redirect is None: redirect = self._RedirectFromCodeDotGoogleDotCom() if redirect is not None: return redirect if path.startswith('_'): servlet_path = path[1:] if servlet_path.find('/') == -1: servlet_path += '/' servlet_name, servlet_path = servlet_path.split('/', 1) servlet = _SERVLETS.get(servlet_name) if servlet is None: return Response.NotFound('"%s" servlet not found' % servlet_path) else: servlet_path = path servlet = _DEFAULT_SERVLET return servlet( Request(servlet_path, self._request.host, self._request.headers)).Get()
def Get(self): path = self._request.path if path.startswith('_'): servlet_path = path[1:] if not '/' in servlet_path: servlet_path += '/' servlet_name, servlet_path = servlet_path.split('/', 1) if servlet_name == _FORCE_CRON_TARGET: queue = taskqueue.Queue() queue.purge() time.sleep(2) queue.add(taskqueue.Task(url='/_cron')) return Response.Ok('Cron job started.') if servlet_name == 'enqueue': queue = taskqueue.Queue() queue.add(taskqueue.Task(url='/%s' % servlet_path)) return Response.Ok('Task enqueued.') servlet = _SERVLETS.get(servlet_name) if servlet is None: return Response.NotFound('"%s" servlet not found' % servlet_path) else: servlet_path = path servlet = _DEFAULT_SERVLET return servlet( Request(servlet_path, self._request.host, self._request.headers, self._request.arguments)).Get()
def Get(self): ''' Render the page for a request. ''' # 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('/') server_instance = self._delegate.CreateServerInstance() try: return self._GetSuccessResponse(path, server_instance) except FileNotFoundError: if IsPreviewServer(): logging.error(traceback.format_exc()) # 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: 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.warning('No 404.html found in %s' % path) return Response.NotFound('Not Found', headers=_MakeHeaders('text/plain'))
def Get(self): path = self._request.path if path.startswith('_'): servlet_path = path[1:] if not '/' in servlet_path: servlet_path += '/' servlet_name, servlet_path = servlet_path.split('/', 1) servlet = _SERVLETS.get(servlet_name) if servlet is None: return Response.NotFound('"%s" servlet not found' % servlet_path) else: servlet_path = path servlet = _DEFAULT_SERVLET return servlet( Request(servlet_path, self._request.host, self._request.headers)).Get()
def Get(self): ''' Render the page for a request. ''' # 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) templates = server_instance.template_data_source_factory.Create( self._request, path) 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'): content = server_instance.example_zipper.Create( path[len('extensions/'):-len('.zip')]) content_type = 'application/zip' elif path.startswith('extensions/examples/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.host_file_system.ReadSingle( '%s/%s' % (svn_constants.DOCS_PATH, path[len('extensions/'):]), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.startswith('static/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.host_file_system.ReadSingle( ('%s/%s' % (svn_constants.DOCS_PATH, path)), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.endswith('.html'): content = templates.Render(path) content_type = 'text/html' except FileNotFoundError: logging.warning(traceback.format_exc()) content = None headers = {'x-frame-options': 'sameorigin'} if content is None: doc_class = path.split('/', 1)[0] content = templates.Render('%s/404' % doc_class) if not content: content = templates.Render('extensions/404') return Response.NotFound(content, headers=headers) if not 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)
def Get(self): ''' Render the page for a request. ''' headers = self._request.headers channel, path = BranchUtility.SplitChannelNameFromPath( self._request.path) if path.split('/')[-1] == 'redirects.json': return Response.Ok('') if channel == self._default_channel: return Response.Redirect('/' + path) if channel is None: channel = self._default_channel server_instance = self._delegate.CreateServerInstanceForChannel( channel) redirect = server_instance.redirector.Redirect(self._request.host, path) if redirect is not None: if (channel != self._default_channel and not urlsplit(redirect).scheme in ('http', 'https')): redirect = '/%s%s' % (channel, redirect) return Response.Redirect(redirect) canonical_path = server_instance.path_canonicalizer.Canonicalize(path) redirect = canonical_path.lstrip('/') if path != redirect: if channel is not None: redirect = '%s/%s' % (channel, canonical_path) return Response.Redirect('/' + redirect) templates = server_instance.template_data_source_factory.Create( self._request, path) content = None content_type = None try: if fnmatch(path, 'extensions/examples/*.zip'): content = server_instance.example_zipper.Create( path[len('extensions/'):-len('.zip')]) content_type = 'application/zip' elif path.startswith('extensions/examples/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.content_cache.GetFromFile( '%s/%s' % (svn_constants.DOCS_PATH, path[len('extensions/'):]), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.startswith('static/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.content_cache.GetFromFile( ('%s/%s' % (svn_constants.DOCS_PATH, path)), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.endswith('.html'): content = templates.Render(path) content_type = 'text/html' except FileNotFoundError: logging.warning(traceback.format_exc()) content = None headers = {'x-frame-options': 'sameorigin'} if content is None: doc_class = path.split('/', 1)[0] content = templates.Render('%s/404' % doc_class) if not content: content = templates.Render('extensions/404') return Response.NotFound(content, headers=headers) if not 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)
def Get(self): path_with_channel, headers = (self._request.path, self._request.headers) # Redirect "extensions" and "extensions/" to "extensions/index.html", etc. if (os.path.splitext(path_with_channel)[1] == '' and path_with_channel.find('/') == -1): path_with_channel += '/' if path_with_channel.endswith('/'): return Response.Redirect('/%sindex.html' % path_with_channel) channel, path = BranchUtility.SplitChannelNameFromPath( path_with_channel) if channel == self._default_channel: return Response.Redirect('/%s' % path) if channel is None: channel = self._default_channel server_instance = self._delegate.CreateServerInstanceForChannel( channel) canonical_path = ( server_instance.path_canonicalizer.Canonicalize(path).lstrip('/')) if path != canonical_path: redirect_path = (canonical_path if channel is None else '%s/%s' % (channel, canonical_path)) return Response.Redirect('/%s' % redirect_path) templates = server_instance.template_data_source_factory.Create( self._request, path) content = None content_type = None try: if fnmatch(path, 'extensions/examples/*.zip'): content = server_instance.example_zipper.Create( path[len('extensions/'):-len('.zip')]) content_type = 'application/zip' elif path.startswith('extensions/examples/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.content_cache.GetFromFile( '%s/%s' % (svn_constants.DOCS_PATH, path[len('extensions/'):]), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.startswith('static/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.content_cache.GetFromFile( ('%s/%s' % (svn_constants.DOCS_PATH, path)), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.endswith('.html'): content = templates.Render(path) content_type = 'text/html' except FileNotFoundError as e: logging.warning(traceback.format_exc()) content = None headers = {'x-frame-options': 'sameorigin'} if content is None: doc_class = path.split('/', 1)[0] content = templates.Render('%s/404' % doc_class) if not content: content = templates.Render('extensions/404') return Response.NotFound(content, headers=headers) if not 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)
def Get(self, server_instance=None): path_with_channel, headers = (self._request.path.lstrip('/'), self._request.headers) # Redirect "extensions" and "extensions/" to "extensions/index.html", etc. if (os.path.splitext(path_with_channel)[1] == '' and path_with_channel.find('/') == -1): path_with_channel += '/' if path_with_channel.endswith('/'): return Response.Redirect(path_with_channel + 'index.html') channel, path = BranchUtility.SplitChannelNameFromPath( path_with_channel) if channel == _DEFAULT_CHANNEL: return Response.Redirect('/%s' % path) if channel is None: channel = _DEFAULT_CHANNEL # AppEngine instances should never need to call out to SVN. That should # only ever be done by the cronjobs, which then write the result into # DataStore, which is as far as instances look. To enable this, crons can # pass a custom (presumably online) ServerInstance into Get(). # # Why? SVN is slow and a bit flaky. Cronjobs failing is annoying but # temporary. Instances failing affects users, and is really bad. # # Anyway - to enforce this, we actually don't give instances access to SVN. # If anything is missing from datastore, it'll be a 404. If the cronjobs # don't manage to catch everything - uhoh. On the other hand, we'll figure # it out pretty soon, and it also means that legitimate 404s are caught # before a round trip to SVN. if server_instance is None: # The ALWAYS_ONLINE thing is for tests and preview.py that shouldn't need # to run the cron before rendering things. constructor = (ServerInstance.CreateOnline if _ALWAYS_ONLINE else ServerInstance.GetOrCreateOffline) server_instance = constructor(channel) canonical_path = server_instance.path_canonicalizer.Canonicalize(path) if path != canonical_path: return Response.Redirect( canonical_path if channel is None else '%s/%s' % (channel, canonical_path)) templates = server_instance.template_data_source_factory.Create( self._request, path) content = None content_type = None try: if fnmatch(path, 'extensions/examples/*.zip'): content = server_instance.example_zipper.Create( path[len('extensions/'):-len('.zip')]) content_type = 'application/zip' elif path.startswith('extensions/examples/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.content_cache.GetFromFile( '%s/%s' % (svn_constants.DOCS_PATH, path[len('extensions/'):]), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.startswith('static/'): mimetype = mimetypes.guess_type(path)[0] or 'text/plain' content = server_instance.content_cache.GetFromFile( ('%s/%s' % (svn_constants.DOCS_PATH, path)), binary=_IsBinaryMimetype(mimetype)) content_type = mimetype elif path.endswith('.html'): content = templates.Render(path) content_type = 'text/html' except FileNotFoundError as e: logging.warning(traceback.format_exc()) content = None headers = {'x-frame-options': 'sameorigin'} if content is None: return Response.NotFound(templates.Render('404'), headers=headers) if not 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)