Exemplo n.º 1
0
def render_object(obj,
                  path,
                  where,
                  append_html=True,
                  output_root='',
                  raise_errors=False):
    path = path.strip('/')
    assert '..' not in path
    outputfile = os.path.join(where, path)
    outputdir = os.path.dirname(outputfile)
    environ = {'SERVER_NAME': 'localhost', 'SERVER_PORT': '80'}
    stdin = StringIO()
    response = Response(stdout=sys.stdout, stderr=sys.stderr)
    request = Request(stdin, environ, response)
    if output_root:
        request['SERVER_URL'] = relpath(output_root, outputdir)
    setDefaultSkin(request)
    app = Application().__of__(RequestContainer(REQUEST=request))
    obj = obj.__of__(app)
    request.other['VirtualRootPhysicalPath'] = obj.getPhysicalPath()
    obj = obj.unrestrictedTraverse(path)
    if getattr(obj, 'index_html', None) is not None:
        obj = obj.index_html
    try:
        result = mapply(obj, request.args, request)
    except Exception, e:
        print >> sys.stderr, "cannot render %s: %s: %s" % (
            path, e.__class__.__name__, e)
        if raise_errors:
            raise
Exemplo n.º 2
0
def publish_module(environ, start_response,
                   _publish=publish,                # only for testing
                   _response_factory=WSGIResponse,  # only for testing
                   _request_factory=HTTPRequest,    # only for testing
                  ):
    status = 200
    stdout = StringIO()
    stderr = StringIO()
    response = _response_factory(stdout=stdout, stderr=stderr)
    response._http_version = environ['SERVER_PROTOCOL'].split('/')[1]
    response._http_connection = environ.get('CONNECTION_TYPE', 'close')
    response._server_version = environ.get('SERVER_SOFTWARE')

    request = _request_factory(environ['wsgi.input'], environ, response)

    if 'repoze.tm.active' in environ:
        # NOTE: registerSynch is a no-op after the first request
        transaction.manager.registerSynch(_request_closer_for_repoze_tm)
        txn = transaction.get()
        _request_closer_for_repoze_tm.add(txn, request)

    setDefaultSkin(request)

    try:
        response = _publish(request, 'Zope2')
    except Unauthorized, v:
        response._unauthorized()
Exemplo n.º 3
0
    def _makeRequest(self,
                     stdin=None,
                     environ=None,
                     response=None,
                     clean=1,
                     stdout=None):
        from ZPublisher.HTTPRequest import HTTPRequest
        from ZPublisher.HTTPResponse import HTTPResponse

        if stdin is None:
            from StringIO import StringIO
            stdin = StringIO()

        if stdout is None:
            from StringIO import StringIO
            stdout = StringIO()

        if environ is None:
            environ = {}

        if 'SERVER_NAME' not in environ:
            environ['SERVER_NAME'] = 'http://localhost'

        if 'SERVER_PORT' not in environ:
            environ['SERVER_PORT'] = '8080'

        if response is None:
            response = HTTPResponse(stdout=stdout)

        req = HTTPRequest(stdin, environ, response, clean)
        setDefaultSkin(req)
        return req
def render_object(obj, path, where, append_html=True, output_root='',
                  raise_errors=False):
    path = path.strip('/')
    assert '..' not in path
    outputfile = os.path.join(where, path)
    outputdir = os.path.dirname(outputfile)
    environ = {'SERVER_NAME': 'localhost',
               'SERVER_PORT': '80'}
    stdin = StringIO()
    response = Response(stdout=sys.stdout, stderr=sys.stderr)
    request = Request(stdin, environ, response)
    if output_root:
        request['SERVER_URL'] = relpath(output_root, outputdir)
    setDefaultSkin(request)
    app = Application().__of__(RequestContainer(REQUEST=request))
    obj = obj.__of__(app)
    request.other['VirtualRootPhysicalPath'] = obj.getPhysicalPath()
    obj = obj.unrestrictedTraverse(path)
    if getattr(obj, 'index_html', None) is not None:
        obj = obj.index_html
    try:
        result = mapply(obj, request.args, request)
    except Exception, e:
        print >> sys.stderr, "cannot render %s: %s: %s" % (path, e.__class__.__name__, e)
        if raise_errors:
            raise
Exemplo n.º 5
0
    def test_retry_keeps_everything(self):
        """lowlevel test for retry (see #98440)"""
        from zope.publisher.browser import TestRequest
        from zope.publisher.skinnable import setDefaultSkin
        from zope.publisher.interfaces import IDefaultSkin
        from zope.publisher.interfaces.browser import IBrowserRequest
        from zope.publisher.interfaces.browser import IBrowserSkinType
        # create a retryable request
        request = TestRequest()
        self.assertTrue(request.supportsRetry())
        # create a skin and register it as the default skin
        class ISomeSkin(Interface):
            pass
        alsoProvides(ISomeSkin, IBrowserSkinType)
        provideAdapter(ISomeSkin, (IBrowserRequest,), IDefaultSkin)
        # set the default skin for the request
        setDefaultSkin(request)

        # create a retried request
        retried = request.retry()

        # the requests are not the same
        self.assertTrue(request is not retried)
        # the requests both provide the default skin
        self.assertTrue(ISomeSkin.providedBy(request))
        self.assertTrue(ISomeSkin.providedBy(retried))
Exemplo n.º 6
0
    def test_retry_keeps_everything(self):
        """lowlevel test for retry (see #98440)"""
        from zope.publisher.browser import TestRequest
        from zope.publisher.skinnable import setDefaultSkin
        from zope.publisher.interfaces import IDefaultSkin
        from zope.publisher.interfaces.browser import IBrowserRequest
        from zope.publisher.interfaces.browser import IBrowserSkinType
        # create a retryable request
        request = TestRequest()
        self.assertTrue(request.supportsRetry())

        # create a skin and register it as the default skin
        class ISomeSkin(Interface):
            pass

        alsoProvides(ISomeSkin, IBrowserSkinType)
        provideAdapter(ISomeSkin, (IBrowserRequest, ), IDefaultSkin)
        # set the default skin for the request
        setDefaultSkin(request)

        # create a retried request
        retried = request.retry()

        # the requests are not the same
        self.assertTrue(request is not retried)
        # the requests both provide the default skin
        self.assertTrue(ISomeSkin.providedBy(request))
        self.assertTrue(ISomeSkin.providedBy(retried))
Exemplo n.º 7
0
def transaction_pubevents(request, tm=transaction.manager):
    ok_exception = None
    try:
        setDefaultSkin(request)
        newInteraction()
        tm.begin()
        notify(pubevents.PubStart(request))
        try:
            yield None
        except (HTTPOk, HTTPRedirection) as exc:
            ok_exception = exc

        notify(pubevents.PubBeforeCommit(request))
        if tm.isDoomed():
            tm.abort()
        else:
            tm.commit()
        notify(pubevents.PubSuccess(request))
    except Exception:
        exc_info = sys.exc_info()
        notify(
            pubevents.PubBeforeAbort(request, exc_info,
                                     request.supports_retry()))
        tm.abort()
        notify(
            pubevents.PubFailure(request, exc_info, request.supports_retry()))
        raise
    finally:
        endInteraction()
        if ok_exception is not None:
            raise ok_exception
    def _makeRequest(self, stdin=None, environ=None,
                     response=None, clean=1, stdout=None):
        from ZPublisher.HTTPRequest import HTTPRequest
        from ZPublisher.HTTPResponse import HTTPResponse

        if stdin is None:
            from StringIO import StringIO
            stdin = StringIO()

        if stdout is None:
            from StringIO import StringIO
            stdout = StringIO()

        if environ is None:
            environ = {}

        if 'SERVER_NAME' not in environ:
            environ['SERVER_NAME'] = 'http://localhost'

        if 'SERVER_PORT' not in environ:
            environ['SERVER_PORT'] = '8080'

        if response is None:
            response = HTTPResponse(stdout=stdout)

        req = HTTPRequest(stdin, environ, response, clean)
        setDefaultSkin(req)
        return req
Exemplo n.º 9
0
def publish_module(
        environ,
        start_response,
        _publish=publish,  # only for testing
        _response_factory=WSGIResponse,  # only for testing
        _request_factory=HTTPRequest,  # only for testing
):
    status = 200
    stdout = StringIO()
    stderr = StringIO()
    response = _response_factory(stdout=stdout, stderr=stderr)
    response._http_version = environ['SERVER_PROTOCOL'].split('/')[1]
    response._http_connection = environ.get('CONNECTION_TYPE', 'close')
    response._server_version = environ.get('SERVER_SOFTWARE')

    request = _request_factory(environ['wsgi.input'], environ, response)

    if 'repoze.tm.active' in environ:
        # NOTE: registerSynch is a no-op after the first request
        transaction.manager.registerSynch(_request_closer_for_repoze_tm)
        txn = transaction.get()
        _request_closer_for_repoze_tm.add(txn, request)

    setDefaultSkin(request)

    try:
        response = _publish(request, 'Zope2')
    except Unauthorized, v:
        response._unauthorized()
Exemplo n.º 10
0
def transaction_pubevents(request, response, tm=transaction.manager):
    try:
        setDefaultSkin(request)
        newInteraction()
        tm.begin()
        notify(pubevents.PubStart(request))

        yield

        notify(pubevents.PubBeforeCommit(request))
        if tm.isDoomed():
            tm.abort()
        else:
            tm.commit()
        notify(pubevents.PubSuccess(request))
    except Exception as exc:
        # Normalize HTTP exceptions
        # (For example turn zope.publisher NotFound into zExceptions NotFound)
        exc_type, _ = upgradeException(exc.__class__, None)
        if not isinstance(exc, exc_type):
            exc = exc_type(str(exc))

        # Create new exc_info with the upgraded exception.
        exc_info = (exc_type, exc, sys.exc_info()[2])

        try:
            # Raise exception from app if handle-errors is False
            # (set by zope.testbrowser in some cases)
            if request.environ.get('x-wsgiorg.throw_errors', False):
                reraise(*exc_info)

            if isinstance(exc, Unauthorized):
                # _unauthorized modifies the response in-place. If this hook
                # is used, an exception view for Unauthorized has to merge
                # the state of the response and the exception instance.
                exc.setRealm(response.realm)
                response._unauthorized()
                response.setStatus(exc.getStatus())

            # Handle exception view
            exc_view_created = _exc_view_created_response(
                exc, request, response)

            notify(
                pubevents.PubBeforeAbort(request, exc_info,
                                         request.supports_retry()))
            tm.abort()
            notify(
                pubevents.PubFailure(request, exc_info,
                                     request.supports_retry()))

            if not (exc_view_created or isinstance(exc, Unauthorized)):
                reraise(*exc_info)
        finally:
            # Avoid traceback / exception reference cycle.
            del exc, exc_info
    finally:
        endInteraction()
Exemplo n.º 11
0
 def request(self, environ):
     method = environ.get('REQUEST_METHOD', 'GET').upper()
     if method in browser_methods:
         request_factory = BrowserRequest
     else:
         request_factory = HTTPRequest
     req =  request_factory(environ['wsgi.input'], environ)
     setDefaultSkin(req)
     return req
Exemplo n.º 12
0
def transaction_pubevents(request, response, tm=transaction.manager):
    try:
        setDefaultSkin(request)
        newInteraction()
        tm.begin()
        notify(pubevents.PubStart(request))

        yield

        notify(pubevents.PubBeforeCommit(request))
        if tm.isDoomed():
            tm.abort()
        else:
            tm.commit()
        notify(pubevents.PubSuccess(request))
    except Exception as exc:
        # Normalize HTTP exceptions
        # (For example turn zope.publisher NotFound into zExceptions NotFound)
        exc_type, _ = upgradeException(exc.__class__, None)
        if not isinstance(exc, exc_type):
            exc = exc_type(str(exc))

        # Create new exc_info with the upgraded exception.
        exc_info = (exc_type, exc, sys.exc_info()[2])

        try:
            # Raise exception from app if handle-errors is False
            # (set by zope.testbrowser in some cases)
            if request.environ.get('x-wsgiorg.throw_errors', False):
                reraise(*exc_info)

            if isinstance(exc, Unauthorized):
                # _unauthorized modifies the response in-place. If this hook
                # is used, an exception view for Unauthorized has to merge
                # the state of the response and the exception instance.
                exc.setRealm(response.realm)
                response._unauthorized()
                response.setStatus(exc.getStatus())

            # Handle exception view
            exc_view_created = _exc_view_created_response(
                exc, request, response)

            notify(pubevents.PubBeforeAbort(
                request, exc_info, request.supports_retry()))
            tm.abort()
            notify(pubevents.PubFailure(
                request, exc_info, request.supports_retry()))

            if not (exc_view_created or isinstance(exc, Unauthorized)):
                reraise(*exc_info)
        finally:
            # Avoid traceback / exception reference cycle.
            del exc, exc_info
    finally:
        endInteraction()
Exemplo n.º 13
0
    def makeRequest(self, path=''):
        env = {"HTTP_HOST": 'localhost', "HTTP_REFERER": 'localhost'}
        p = path.split('?')
        if len(p) == 1:
            env['PATH_INFO'] = p[0]

        request = BrowserRequest(StringIO(''), env)
        request.setPublication(DummyPublication(self.app))
        setDefaultSkin(request)
        return request
Exemplo n.º 14
0
    def __call__(self, input_stream, env):
        method = env.get('REQUEST_METHOD', 'GET').upper()
        request_class, publication_class = chooseClasses(method, env)

        publication = BrowserPublication()
        request = request_class(input_stream, env)
        request.setPublication(publication)
        if ISkinnable.providedBy(request):
            # only ISkinnable requests have skins
            setDefaultSkin(request)
        return request
Exemplo n.º 15
0
    def makeRequest(self, path=''):
        env = {"HTTP_HOST": 'localhost',
               "HTTP_REFERER": 'localhost'}
        p = path.split('?')
        if len(p) == 1:
            env['PATH_INFO'] = p[0]

        request = BrowserRequest(StringIO(''), env)
        request.setPublication(DummyPublication(self.app))
        setDefaultSkin(request)
        return request
Exemplo n.º 16
0
def publish(app, debug_mode, request, response):
    """
    Used in place of ::

        from ZPublisher.Publish import publish_module
            publish_module('Zope2',
                           debug=not handle_errors,
                           request=request,
                           response=response)

    Warning: some calls made by ``publish_module`` have been removed
    (maybe wrongly).
    """

    from ZPublisher.mapply import mapply
    from ZPublisher.Publish import call_object
    from ZPublisher.Publish import missing_name
    from ZPublisher.Publish import dont_publish_class

    from zope.publisher.interfaces import ISkinnable
    from zope.publisher.skinnable import setDefaultSkin

    if ISkinnable.providedBy(request):
        setDefaultSkin(request)
    request.processInputs()

    if debug_mode:
        response.debug_mode = debug_mode
    if not request.get('REMOTE_USER', None):
        response.realm = 'Zope2'

    # Get the path list.
    # According to RFC1738 a trailing space in the path is valid.
    path = request.get('PATH_INFO')

    request['PARENTS'] = [app]

    from Zope2.App.startup import validated_hook
    object = request.traverse(path, validated_hook=validated_hook)

    result = mapply(object, request.args, request,
                  call_object, 1,
                  missing_name,
                  dont_publish_class,
                  request, bind=1)

    if result is not response:
        response.setBody(result)
Exemplo n.º 17
0
    def __call__(self, input_stream, env):
        """See `zope.app.publication.interfaces.IPublicationRequestFactory`"""
        method = env.get('REQUEST_METHOD', 'GET').upper()
        request_class, publication_class = chooseClasses(method, env)

        publication = self._publication_cache.get(publication_class)
        if publication is None:
            publication = publication_class(self._db)
            self._publication_cache[publication_class] = publication

        request = request_class(input_stream, env)
        request.setPublication(publication)
        if ISkinnable.providedBy(request):
            # only ISkinnable requests have skins
            setDefaultSkin(request)
        return request
Exemplo n.º 18
0
    def __call__(self, input_stream, env):
        """See `zope.app.publication.interfaces.IPublicationRequestFactory`"""
        method = env.get('REQUEST_METHOD', 'GET').upper()
        request_class, publication_class = chooseClasses(method, env)

        publication = self._publication_cache.get(publication_class)
        if publication is None:
            publication = publication_class(self._db)
            self._publication_cache[publication_class] = publication

        request = request_class(input_stream, env)
        request.setPublication(publication)
        if ISkinnable.providedBy(request):
            # only ISkinnable requests have skins
            setDefaultSkin(request)
        return request
Exemplo n.º 19
0
    def retry(self):
        'See IPublisherRequest'
        count = getattr(self, '_retry_count', 0)
        self._retry_count = count + 1

        request = self.__class__(
            # Use the cache stream as the new input stream.
            body_instream=self._body_instream.getCacheStream(),
            environ=self._orig_env,
            response=self.response.retry(),
        )
        # restore the default skin
        if ISkinnable.providedBy(self):
            # only ISkinnable requests have skins
            setDefaultSkin(request)

        request.setPublication(self.publication)
        request._retry_count = self._retry_count
        return request
Exemplo n.º 20
0
    def retry(self):
        'See IPublisherRequest'
        count = getattr(self, '_retry_count', 0)
        self._retry_count = count + 1

        request = self.__class__(
            # Use the cache stream as the new input stream.
            body_instream=self._body_instream.getCacheStream(),
            environ=self._orig_env,
            response=self.response.retry(),
            )
        # restore the default skin
        if ISkinnable.providedBy(self):
            # only ISkinnable requests have skins
            setDefaultSkin(request)

        request.setPublication(self.publication)
        request._retry_count = self._retry_count
        return request
Exemplo n.º 21
0
    def makeRequest(self, path='', basic=None, form=None, env={}):
        """Creates a new request object.

        Arguments:
          path   -- the path to be traversed (e.g. "/folder1/index.html")
          basic  -- basic HTTP authentication credentials ("user:password")
          form   -- a dictionary emulating a form submission
                    (Note that field values should be Unicode strings)
          env    -- a dictionary of additional environment variables
                    (You can emulate HTTP request header
                       X-Header: foo
                     by adding 'HTTP_X_HEADER': 'foo' to env)
        """
        environment = {"HTTP_HOST": 'localhost',
                       "HTTP_COOKIE": self.httpCookie(path)}
        environment.update(env)
        app = FunctionalTestSetup().getApplication()
        request = app._request(path, '',
                               environment=environment,
                               basic=basic, form=form,
                               request=BrowserRequest)
        setDefaultSkin(request)
        return request
Exemplo n.º 22
0
    def __call__(self, request_string, handle_errors=True, form=None):
        # Commit work done by previous python code.
        commit()

        # Discard leading white space to make call layout simpler
        request_string = request_string.lstrip()

        # split off and parse the command line
        l = request_string.find('\n')
        command_line = request_string[:l].rstrip()
        request_string = request_string[l+1:]
        method, path, protocol = command_line.split()

        instream = StringIO(request_string)
        environment = {"HTTP_COOKIE": self.httpCookie(path),
                       "HTTP_HOST": 'localhost',
                       "HTTP_REFERER": 'localhost',
                       "REQUEST_METHOD": method,
                       "SERVER_PROTOCOL": protocol,
                       }

        headers = [split_header(header)
                   for header in rfc822.Message(instream).headers]
        for name, value in headers:
            name = ('_'.join(name.upper().split('-')))
            if name not in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
                name = 'HTTP_' + name
            environment[name] = value.rstrip()

        auth_key = 'HTTP_AUTHORIZATION'
        if environment.has_key(auth_key):
            environment[auth_key] = auth_header(environment[auth_key])

        old_site = getSite()
        setSite(None)

        request_cls, publication_cls = self.chooseRequestClass(method, path,
                                                               environment)
        app = FunctionalTestSetup().getApplication()

        request = app._request(
            path, instream,
            environment=environment,
            request=request_cls, publication=publication_cls)
        if ISkinnable.providedBy(request):
            # only ISkinnable requests have skins
            setDefaultSkin(request)

        if form is not None:
            if request.form:
                raise ValueError("only one set of form values can be provided")
            request.form = form

        request = publish(request, handle_errors=handle_errors)

        response = ResponseWrapper(
            request.response, path,
            omit=('x-content-type-warning', 'x-powered-by'),
            )

        self.saveCookies(response)
        setSite(old_site)

        # sync Python connection:
        getRootFolder()._p_jar.sync()

        return response
Exemplo n.º 23
0
def publish(
    request,
    module_name,
    after_list,
    debug=0,
    # Optimize:
    call_object=call_object,
    missing_name=missing_name,
    dont_publish_class=dont_publish_class,
    mapply=mapply,
):

    (bobo_before, bobo_after, object, realm, debug_mode, err_hook,
     validated_hook, transactions_manager) = get_module_info(module_name)

    parents = None
    response = None

    try:
        notify(pubevents.PubStart(request))
        # TODO pass request here once BaseRequest implements IParticipation
        newInteraction()

        request.processInputs()

        request_get = request.get
        response = request.response

        # First check for "cancel" redirect:
        if request_get('SUBMIT', '').strip().lower() == 'cancel':
            cancel = request_get('CANCEL_ACTION', '')
            if cancel:
                # Relative URLs aren't part of the spec, but are accepted by
                # some browsers.
                for part, base in zip(
                        urlparse(cancel)[:3],
                        urlparse(request['BASE1'])[:3]):
                    if not part:
                        continue
                    if not part.startswith(base):
                        cancel = ''
                        break
            if cancel:
                raise Redirect(cancel)

        after_list[0] = bobo_after
        if debug_mode:
            response.debug_mode = debug_mode
        if realm and not request.get('REMOTE_USER', None):
            response.realm = realm

        noSecurityManager()
        if bobo_before is not None:
            bobo_before()

        # Get the path list.
        # According to RFC1738 a trailing space in the path is valid.
        path = request_get('PATH_INFO')

        request['PARENTS'] = parents = [object]

        if transactions_manager:
            transactions_manager.begin()

        object = request.traverse(path, validated_hook=validated_hook)

        if IBrowserPage.providedBy(object):
            request.postProcessInputs()

        notify(pubevents.PubAfterTraversal(request))

        if transactions_manager:
            recordMetaData(object, request)

        result = mapply(object,
                        request.args,
                        request,
                        call_object,
                        1,
                        missing_name,
                        dont_publish_class,
                        request,
                        bind=1)
        if result is not response:
            response.setBody(result)

        notify(pubevents.PubBeforeCommit(request))

        if transactions_manager:
            transactions_manager.commit()

        notify(pubevents.PubSuccess(request))
        endInteraction()

        return response
    except:
        # save in order to give 'PubFailure' the original exception info
        exc_info = sys.exc_info()
        # DM: provide nicer error message for FTP
        sm = None
        if response is not None:
            sm = getattr(response, "setMessage", None)

        if sm is not None:
            from asyncore import compact_traceback
            cl, val = sys.exc_info()[:2]
            sm('%s: %s %s' % (getattr(cl, '__name__', cl), val,
                              debug_mode and compact_traceback()[-1] or ''))

        # debug is just used by tests (has nothing to do with debug_mode!)
        if not debug and err_hook is not None:
            retry = False
            if parents:
                parents = parents[0]
            try:
                try:
                    return err_hook(
                        parents,
                        request,
                        sys.exc_info()[0],
                        sys.exc_info()[1],
                        sys.exc_info()[2],
                    )
                except Retry:
                    if not request.supports_retry():
                        return err_hook(
                            parents,
                            request,
                            sys.exc_info()[0],
                            sys.exc_info()[1],
                            sys.exc_info()[2],
                        )
                    retry = True
            finally:
                # Note: 'abort's can fail.
                # Nevertheless, we want end request handling.
                try:
                    try:
                        notify(
                            pubevents.PubBeforeAbort(request, exc_info, retry))
                    finally:
                        if transactions_manager:
                            transactions_manager.abort()
                finally:
                    endInteraction()
                    notify(pubevents.PubFailure(request, exc_info, retry))

            # Only reachable if Retry is raised and request supports retry.
            newrequest = request.retry()
            request.close()  # Free resources held by the request.

            # Set the default layer/skin on the newly generated request
            if ISkinnable.providedBy(newrequest):
                setDefaultSkin(newrequest)
            try:
                return publish(newrequest, module_name, after_list, debug)
            finally:
                newrequest.close()

        else:
            # Note: 'abort's can fail.
            # Nevertheless, we want end request handling.
            try:
                try:
                    notify(pubevents.PubBeforeAbort(request, exc_info, False))
                finally:
                    if transactions_manager:
                        transactions_manager.abort()
            finally:
                endInteraction()
                notify(pubevents.PubFailure(request, exc_info, False))
            raise
Exemplo n.º 24
0
def publish_module_standard(module_name,
                            stdin=sys.stdin,
                            stdout=sys.stdout,
                            stderr=sys.stderr,
                            environ=os.environ,
                            debug=0,
                            request=None,
                            response=None):
    must_die = 0
    status = 200
    after_list = [None]
    try:
        try:
            if response is None:
                response = Response(stdout=stdout, stderr=stderr)
            else:
                stdout = response.stdout

            # debug is just used by tests (has nothing to do with debug_mode!)
            response.handle_errors = not debug

            if request is None:
                request = Request(stdin, environ, response)

            setRequest(request)

            # make sure that the request we hand over has the
            # default layer/skin set on it; subsequent code that
            # wants to look up views will likely depend on it
            if ISkinnable.providedBy(request):
                setDefaultSkin(request)

            response = publish(request, module_name, after_list, debug=debug)
        except (SystemExit, ImportError):
            # XXX: Rendered ImportErrors were never caught here because they
            # were re-raised as string exceptions. Maybe we should handle
            # ImportErrors like all other exceptions. Currently they are not
            # re-raised at all, so they don't show up here.
            must_die = sys.exc_info()
            request.response.exception(1)
        except:
            # debug is just used by tests (has nothing to do with debug_mode!)
            if debug:
                raise
            request.response.exception()
            status = response.getStatus()

        if response:
            outputBody = getattr(response, 'outputBody', None)
            if outputBody is not None:
                outputBody()
            else:
                response = str(response)
                if response:
                    stdout.write(response)

        # The module defined a post-access function, call it
        if after_list[0] is not None:
            after_list[0]()

    finally:
        if request is not None:
            request.close()
            clearRequest()

    if must_die:
        # Try to turn exception value into an exit code.
        try:
            if hasattr(must_die[1], 'code'):
                code = must_die[1].code
            else:
                code = int(must_die[1])
        except:
            code = must_die[1] and 1 or 0
        if hasattr(request.response, '_requestShutdown'):
            request.response._requestShutdown(code)

        try:
            reraise(must_die[0], must_die[1], must_die[2])
        finally:
            must_die = None

    return status
Exemplo n.º 25
0
def transaction_pubevents(request, response, tm=transaction.manager):
    try:
        setDefaultSkin(request)
        newInteraction()
        tm.begin()
        notify(pubevents.PubStart(request))

        yield

        notify(pubevents.PubBeforeCommit(request))
        if tm.isDoomed():
            tm.abort()
        else:
            tm.commit()
        notify(pubevents.PubSuccess(request))
    except Exception as exc:
        # Normalize HTTP exceptions
        # (For example turn zope.publisher NotFound into zExceptions NotFound)
        exc_type, _ = upgradeException(exc.__class__, None)
        if not isinstance(exc, exc_type):
            exc = exc_type(str(exc))

        # Create new exc_info with the upgraded exception.
        exc_info = (exc_type, exc, sys.exc_info()[2])

        try:
            # Raise exception from app if handle-errors is False
            # (set by zope.testbrowser in some cases)
            if request.environ.get('x-wsgiorg.throw_errors', False):
                reraise(*exc_info)

            retry = False
            unauth = False
            debug_exc = getattr(response, 'debug_exceptions', False)

            # If the exception is transient and the request can be retried,
            # shortcut further processing. It makes no sense to have an
            # exception view registered for this type of exception.
            if isinstance(exc, TransientError) and request.supports_retry():
                retry = True
            else:
                # Handle exception view. Make sure an exception view that
                # blows up doesn't leave the user e.g. unable to log in.
                try:
                    exc_view_created = _exc_view_created_response(
                        exc, request, response)
                except Exception:
                    exc_view_created = False

                # _unauthorized modifies the response in-place. If this hook
                # is used, an exception view for Unauthorized has to merge
                # the state of the response and the exception instance.
                if isinstance(exc, Unauthorized):
                    unauth = True
                    exc.setRealm(response.realm)
                    response._unauthorized()
                    response.setStatus(exc.getStatus())

            # Notify subscribers that this request is failing.
            notify(pubevents.PubBeforeAbort(request, exc_info, retry))
            tm.abort()
            notify(pubevents.PubFailure(request, exc_info, retry))

            if retry or \
               (not unauth and (debug_exc or not exc_view_created)):
                reraise(*exc_info)

        finally:
            # Avoid traceback / exception reference cycle.
            del exc, exc_info
    finally:
        endInteraction()
Exemplo n.º 26
0
def publish(request, module_name, after_list, debug=0,
            # Optimize:
            call_object=call_object,
            missing_name=missing_name,
            dont_publish_class=dont_publish_class,
            mapply=mapply,
            ):

    (bobo_before, bobo_after, object, realm, debug_mode, err_hook,
     validated_hook, transactions_manager)= get_module_info(module_name)

    parents=None
    response=None

    try:
        notify(PubStart(request))
        # TODO pass request here once BaseRequest implements IParticipation
        newInteraction()

        request.processInputs()

        request_get=request.get
        response=request.response

        # First check for "cancel" redirect:
        if request_get('SUBMIT', '').strip().lower() == 'cancel':
            cancel = request_get('CANCEL_ACTION', '')
            if cancel:
                # Relative URLs aren't part of the spec, but are accepted by
                # some browsers.
                for part, base in zip(urlparse(cancel)[:3],
                                      urlparse(request['BASE1'])[:3]):
                    if not part:
                        continue
                    if not part.startswith(base):
                        cancel = ''
                        break
            if cancel:
                raise Redirect, cancel

        after_list[0]=bobo_after
        if debug_mode:
            response.debug_mode=debug_mode
        if realm and not request.get('REMOTE_USER',None):
            response.realm=realm

        if bobo_before is not None:
            bobo_before()

        # Get the path list.
        # According to RFC1738 a trailing space in the path is valid.
        path=request_get('PATH_INFO')

        request['PARENTS']=parents=[object]

        if transactions_manager:
            transactions_manager.begin()

        object=request.traverse(path, validated_hook=validated_hook)

        notify(PubAfterTraversal(request))

        if transactions_manager:
            transactions_manager.recordMetaData(object, request)

        result=mapply(object, request.args, request,
                      call_object,1,
                      missing_name,
                      dont_publish_class,
                      request, bind=1)

        if result is not response:
            response.setBody(result)

        notify(PubBeforeCommit(request))

        if transactions_manager:
            transactions_manager.commit()
        endInteraction()

        notify(PubSuccess(request))

        return response
    except:
        # save in order to give 'PubFailure' the original exception info
        exc_info = sys.exc_info()
        # DM: provide nicer error message for FTP
        sm = None
        if response is not None:
            sm = getattr(response, "setMessage", None)

        if sm is not None:
            from asyncore import compact_traceback
            cl,val= sys.exc_info()[:2]
            sm('%s: %s %s' % (
                getattr(cl,'__name__',cl), val,
                debug_mode and compact_traceback()[-1] or ''))

        # debug is just used by tests (has nothing to do with debug_mode!)
        if not debug and err_hook is not None:
            retry = False
            if parents:
                parents=parents[0]
            try:
                try:
                    return err_hook(parents, request,
                                    sys.exc_info()[0],
                                    sys.exc_info()[1],
                                    sys.exc_info()[2],
                                    )
                except Retry:
                    if not request.supports_retry():
                        return err_hook(parents, request,
                                        sys.exc_info()[0],
                                        sys.exc_info()[1],
                                        sys.exc_info()[2],
                                        )
                    retry = True
            finally:
                # Note: 'abort's can fail. Nevertheless, we want end request handling
                try:
                    try:
                        notify(PubBeforeAbort(request, exc_info, retry))
                    finally:
                        if transactions_manager:
                            transactions_manager.abort()
                finally:
                    endInteraction()
                    notify(PubFailure(request, exc_info, retry))

            # Only reachable if Retry is raised and request supports retry.
            newrequest=request.retry()
            request.close()  # Free resources held by the request.

            # Set the default layer/skin on the newly generated request
            if ISkinnable.providedBy(newrequest):
                setDefaultSkin(newrequest)
            try:
                return publish(newrequest, module_name, after_list, debug)
            finally:
                newrequest.close()

        else:
            # Note: 'abort's can fail. Nevertheless, we want end request handling
            try:
                try:
                    notify(PubBeforeAbort(request, exc_info, False))
                finally:
                    if transactions_manager:
                        transactions_manager.abort()
            finally:
                endInteraction()
                notify(PubFailure(request, exc_info, False))
            raise
Exemplo n.º 27
0
def transaction_pubevents(request, response, tm=transaction.manager):
    try:
        setDefaultSkin(request)
        newInteraction()
        tm.begin()
        notify(pubevents.PubStart(request))

        yield

        notify(pubevents.PubBeforeCommit(request))
        if tm.isDoomed():
            tm.abort()
        else:
            tm.commit()
        notify(pubevents.PubSuccess(request))
    except Exception as exc:
        # Normalize HTTP exceptions
        # (For example turn zope.publisher NotFound into zExceptions NotFound)
        exc_type, _ = upgradeException(exc.__class__, None)
        if not isinstance(exc, exc_type):
            exc = exc_type(str(exc))

        # Create new exc_info with the upgraded exception.
        exc_info = (exc_type, exc, sys.exc_info()[2])

        try:
            # Raise exception from app if handle-errors is False
            # (set by zope.testbrowser in some cases)
            if request.environ.get('x-wsgiorg.throw_errors', False):
                reraise(*exc_info)

            retry = False
            unauth = False
            debug_exc = getattr(response, 'debug_exceptions', False)

            # If the exception is transient and the request can be retried,
            # shortcut further processing. It makes no sense to have an
            # exception view registered for this type of exception.
            if isinstance(exc, TransientError) and request.supports_retry():
                retry = True
            else:
                # Handle exception view. Make sure an exception view that
                # blows up doesn't leave the user e.g. unable to log in.
                try:
                    exc_view_created = _exc_view_created_response(
                        exc, request, response)
                except Exception:
                    exc_view_created = False

                # _unauthorized modifies the response in-place. If this hook
                # is used, an exception view for Unauthorized has to merge
                # the state of the response and the exception instance.
                if isinstance(exc, Unauthorized):
                    unauth = True
                    exc.setRealm(response.realm)
                    response._unauthorized()
                    response.setStatus(exc.getStatus())

            # Notify subscribers that this request is failing.
            notify(pubevents.PubBeforeAbort(request, exc_info, retry))
            tm.abort()
            notify(pubevents.PubFailure(request, exc_info, retry))

            if retry or \
               (not unauth and (debug_exc or not exc_view_created)):
                reraise(*exc_info)

        finally:
            # Avoid traceback / exception reference cycle.
            del exc, exc_info
    finally:
        endInteraction()
Exemplo n.º 28
0
def publish_module(module_name,
                   stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
                   environ=os.environ, debug=0, request=None, response=None,
                   extra={}):
    """ Adapted from from ZPublisher.Test.publish_module:
    but we handle the response status like given from response.getStatus(),
    otherwise plone internal links will return status=200 for status=404 links,
    which will not throw an error.
    """
    must_die = 0
    status = 200
    after_list = [None]
    from ZPublisher.Response import Response
    from ZPublisher.Request import Request
    from ZPublisher.Publish import publish
    from zope.publisher.interfaces import ISkinnable
    from zope.publisher.skinnable import setDefaultSkin
    try:
        try:
            if response is None:
                response = Response(stdout=stdout, stderr=stderr)
            else:
                stdout = response.stdout

            # debug is just used by tests (has nothing to do with debug_mode!)
            response.handle_errors = not debug

            if request is None:
                request = Request(stdin, environ, response)

            # make sure that the request we hand over has the
            # default layer/skin set on it; subsequent code that
            # wants to look up views will likely depend on it
            if ISkinnable.providedBy(request):
                setDefaultSkin(request)

            for k, v in extra.items():
                request[k] = v
            response = publish(request, module_name, after_list, debug=debug)
        except (SystemExit, ImportError):
            # XXX: Rendered ImportErrors were never caught here because they
            # were re-raised as string exceptions. Maybe we should handle
            # ImportErrors like all other exceptions. Currently they are not
            # re-raised at all, so they don't show up here.
            must_die = sys.exc_info()
            request.response.exception(1)
        except Unauthorized:
            # Handle Unauthorized separately, otherwise it will be displayed as
            # a redirect to the login form
            status = 200
            response = None
        except:
            # debug is just used by tests (has nothing to do with debug_mode!)
            if debug:
                raise
            request.response.exception()
            status = response.getStatus()

        if response:
            # this is our change: otherwise 404 will return 200
            # but we only want "real" 404 - otherwise the list will get full
            # of internal links with edit-links stuff that will return 5xx
            # codes.
            if response.getStatus() in (301, 302, 404):
                status = response.getStatus()

            outputBody = getattr(response, 'outputBody', None)
            if outputBody is not None:
                outputBody()
            else:
                response = str(response)
                if response:
                    stdout.write(response)

        # The module defined a post-access function, call it
        if after_list[0] is not None:
            after_list[0]()

    finally:
        if request is not None:
            request.close()

    if must_die:
        # Try to turn exception value into an exit code.
        try:
            if hasattr(must_die[1], 'code'):
                code = must_die[1].code
            else:
                code = int(must_die[1])
        except:
            code = must_die[1] and 1 or 0
        if hasattr(request.response, '_requestShutdown'):
            request.response._requestShutdown(code)

        try:
            raise must_die[0], must_die[1], must_die[2]
        finally:
            must_die = None

    return status, response
Exemplo n.º 29
0
def publish_module(module_name,
                   stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
                   environ=os.environ, debug=0, request=None, response=None,
                   extra={}):
    must_die=0
    status=200
    after_list=[None]
    from Response import Response
    from Request import Request
    from Publish import publish
    from zope.publisher.interfaces import ISkinnable
    from zope.publisher.skinnable import setDefaultSkin
    try:
        try:
            if response is None:
                response=Response(stdout=stdout, stderr=stderr)
            else:
                stdout=response.stdout

            # debug is just used by tests (has nothing to do with debug_mode!)
            response.handle_errors = not debug

            if request is None:
                request=Request(stdin, environ, response)

            # make sure that the request we hand over has the
            # default layer/skin set on it; subsequent code that
            # wants to look up views will likely depend on it
            if ISkinnable.providedBy(request):
                setDefaultSkin(request)

            for k, v in extra.items(): request[k]=v
            response = publish(request, module_name, after_list, debug=debug)
        except (SystemExit, ImportError):
            # XXX: Rendered ImportErrors were never caught here because they
            # were re-raised as string exceptions. Maybe we should handle
            # ImportErrors like all other exceptions. Currently they are not
            # re-raised at all, so they don't show up here.
            must_die = sys.exc_info()
            request.response.exception(1)
        except:
            # debug is just used by tests (has nothing to do with debug_mode!)
            if debug:
                raise
            request.response.exception()
            status = response.getStatus()

        if response:
            outputBody=getattr(response, 'outputBody', None)
            if outputBody is not None:
                outputBody()
            else:
                response=str(response)
                if response: stdout.write(response)

        # The module defined a post-access function, call it
        if after_list[0] is not None: after_list[0]()

    finally:
        if request is not None: request.close()

    if must_die:
        # Try to turn exception value into an exit code.
        try:
            if hasattr(must_die[1], 'code'):
                code = must_die[1].code
            else: code = int(must_die[1])
        except:
            code = must_die[1] and 1 or 0
        if hasattr(request.response, '_requestShutdown'):
            request.response._requestShutdown(code)

        try: raise must_die[0], must_die[1], must_die[2]
        finally: must_die=None

    return status