Example #1
0
def handler(apachereq):
    """Handles an HTTP request.

    Intended to be called by mod_python, as a handler.

    @param apachereq: An Apache request object.
    """
    # Make the request object into an IVLE request which can be given to views
    req = Request(apachereq, config)

    req.publisher = generate_publisher(
        config.plugin_index[ViewPlugin], ApplicationRoot(req),
        publicmode=req.publicmode)

    try:
        obj, viewcls, subpath = req.publisher.resolve(req.uri.decode('utf-8'))
        try:
            # We 404 if we have a subpath but the view forbids it.
            if not viewcls.subpath_allowed and subpath:
                raise NotFound()

            # Instantiate the view, which should be a BaseView class
            view = viewcls(req, obj, subpath)

            # Check that the request (mainly the user) is permitted to access
            # the view.
            if not view.authorize(req):
                # Indicate the forbidden object if this is an admin.
                if req.user and req.user.admin:
                    raise Unauthorized('Unauthorized: %s' % view)
                else:
                    raise Unauthorized()

            # Non-GET requests from other sites leave us vulnerable to
            # CSRFs. Block them.
            referer = req.headers_in.get('Referer')
            if (referer is None or
                urlparse.urlparse(req.headers_in.get('Referer')).netloc !=
                    req.hostname):
                if req.method != 'GET' and not view.offsite_posts_allowed:
                    raise BadRequest(
                        "Non-GET requests from external sites are forbidden "
                        "for security reasons.")

            # Render the output
            view.render(req)
        except HTTPError, e:
            # A view explicitly raised an HTTP error. Respect it.
            req.status = e.code

            # Try to find a custom error view.
            if hasattr(viewcls, 'get_error_view'):
                errviewcls = viewcls.get_error_view(e)
            else:
                errviewcls = XHTMLView.get_error_view(e)

            if errviewcls:
                errview = errviewcls(req, e, obj)
                errview.render(req)
                return req.OK
            elif e.message:
                req.write(e.message)
                return req.OK
            else:
                return e.code
        except mod_python.apache.SERVER_RETURN:
            # A mod_python-specific Apache error.
            # XXX: We need to raise these because req.throw_error() uses them.
            # Remove this after Google Code issue 117 is fixed.
            raise
        except Exception, e:
            # A non-HTTPError appeared. We have an unknown exception. Panic.
            handle_unknown_exception(req, *sys.exc_info())
            return req.OK
Example #2
0
            # A mod_python-specific Apache error.
            # XXX: We need to raise these because req.throw_error() uses them.
            # Remove this after Google Code issue 117 is fixed.
            raise
        except Exception, e:
            # A non-HTTPError appeared. We have an unknown exception. Panic.
            handle_unknown_exception(req, *sys.exc_info())
            return req.OK
        else:
            # Commit the transaction if we have a store open.
            req.commit()
            return req.OK
    except Unauthorized, e:
        # Resolution failed due to a permission check. Display a pretty
        # error, or maybe a login page.
        XHTMLView.get_error_view(e)(req, e, req.publisher.root).render(req)
        return req.OK
    except PublishingError, e:
        req.status = 404

        if req.user and req.user.admin:
            XHTMLErrorView(req, NotFound('Not found: ' +
                                         str(e.args)), e[0]).render(req)
        else:
            XHTMLErrorView(req, NotFound(), e[0]).render(req)

        return req.OK
    finally:
        # Make sure we close the store.
        req.cleanup()