Exemple #1
0
    def _handle(self, api):
        """Handle a Draco request.

        Supported HTTP methods are GET, HEAD and POST. Files having the
        Draco extension are handled as Draco content. Requests for
        directories are redirected to an index page, all other requests
        are treated as plain file requests.
        """
        request = api.request
        response = api.response

        # Redirect to index?
        filename = request.filename()
        if not filename:
            self._redirect_index(api)
            return

        # Serve a normal file?
        extension = api.config.ns()['extension']
        if request.extension() != extension:
            if request.extension() not in ('css', 'js'):
                raise HTTPResponse, http.HTTP_FORBIDDEN
            handler = FileHandler()
            ret = handler._handle(api)
            return ret

        # Set up shared transaction for the draco model.
        model = api.models.model('draco')
        transaction = model.transaction('shared')
        transaction.set_finalization_policy('COMMIT')

        # Per-request objects
        api.opener = DracoOpener._create(api)
        api.parser = DracoParser._create(api)
        api.rewriter = DracoRewriter._create(api)

        try:
            # Session try/finally block.
            api._export(self)
            self['api'] = api
            self['tr'] = tr
            self['tr_attr'] = tr_attr
            self['tr_mark'] = tr_mark

            # Add "compatiblity" events that make our XHTML framework
            # solution work with internet explorer.
            filter = CompatFilter()
            api.response.add_filter(filter)
            event = CompatEventHandler()
            api.events.add_event_handler(event)

            response.set_template(request.filename())

            api.events.raise_event('pre_request', api)
            self._pre_request(api)

            basename = request.basename()
            try:
                method = getattr(self, basename)
            except AttributeError:
                method = None

            template = response.template()
            if template and not api.opener.access(template):
                template = None

            if not method and not template:
                raise HTTPResponse, http.HTTP_NOT_FOUND

            if hasattr(method, 'norobot') and method.norobot and \
                        api.request.isrobot():
                raise HTTPResponse, http.HTTP_FORBIDDEN

            if method:
                method(api)

            if template:
                output = api.parser.parse(template, namespace=self,
                                          opener=api.opener)
                output = api.rewriter.filter(output)
                mime_type = http.get_mime_type(output)
                response.set_buffering(True)
                response.set_header('Content-Type', mime_type)
                response.set_header('Cache-Control', 'no-cache')
                response.set_header('Content-Length', str(len(output)))
                response.write(output)
                api.events.raise_event('pre_request_flush', api)
                header_only = request.method() == 'HEAD'
                response.flush(header_only)

            api.events.raise_event('post_request', api)
            self._post_request(api)

        finally:
            if api.session:
                api.session.commit()