Пример #1
0
  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'))
Пример #2
0
    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
Пример #3
0
    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)
Пример #4
0
    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'))
Пример #7
0
  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()
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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)
Пример #11
0
    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)