示例#1
0
    def test_decodesPath(self):
        """
        server_name, path_info, and script_name are decoded as UTF-8 before
        being handed to werkzeug.
        """
        request = requestMock(b"/f\xc3\xb6\xc3\xb6")

        _render(self.kr, request)
        kreq = IKleinRequest(request)
        self.assertIsInstance(kreq.mapper.server_name, unicode)
        self.assertIsInstance(kreq.mapper.path_info, unicode)
        self.assertIsInstance(kreq.mapper.script_name, unicode)
示例#2
0
    def render(self, request):
        # Stuff we need to know for the mapper.
        try:
            url_scheme, server_name, server_port, path_info, script_name = \
                _extractURLparts(request)
        except _URLDecodeError as e:
            for what, fail in e.errors:
                log.err(fail, "Invalid encoding in {what}.".format(what=what))
            request.setResponseCode(400)
            return b"Non-UTF-8 encoding in URL."

        # Bind our mapper.
        mapper = self._app.url_map.bind(
            server_name,
            script_name,
            path_info=path_info,
            default_method=request.method,
            url_scheme=url_scheme,
        )
        # Make the mapper available to the view.
        kleinRequest = IKleinRequest(request)
        kleinRequest.mapper = mapper

        # Make sure we'll notice when the connection goes away unambiguously.
        request_finished = [False]

        def _finish(result):
            request_finished[0] = True

        def _execute():
            # Actually doing the match right here. This can cause an exception
            # to percolate up. If that happens it will be handled below in
            # processing_failed, either by a user-registered error handler or
            # one of our defaults.
            (rule, kwargs) = mapper.match(return_rule=True)
            endpoint = rule.endpoint

            # Try pretty hard to fix up prepath and postpath.
            segment_count = self._app.endpoints[endpoint].segment_count
            request.prepath.extend(request.postpath[:segment_count])
            request.postpath = request.postpath[segment_count:]

            request.notifyFinish().addBoth(_finish)

            # Standard Twisted Web stuff. Defer the method action, giving us
            # something renderable or printable. Return NOT_DONE_YET and set up
            # the incremental renderer.
            d = defer.maybeDeferred(self._app.execute_endpoint,
                                    endpoint,
                                    request,
                                    **kwargs)

            request.notifyFinish().addErrback(lambda _: d.cancel())

            return d

        d = defer.maybeDeferred(_execute)

        def write_response(r):
            if r is not _StandInResource:
                if isinstance(r, unicode):
                    r = r.encode('utf-8')

                if (r is not None) and (r != NOT_DONE_YET):
                    request.write(r)

                if not request_finished[0]:
                    request.finish()

        def process(r):
            """
            Recursively go through r and any child Resources until something
            returns an IRenderable, then render it and let the result of that
            bubble back up.
            """

            if IResource.providedBy(r):
                request.render(getChildForRequest(r, request))
                return _StandInResource

            if IRenderable.providedBy(r):
                return renderElement(request, r)

            return r

        d.addCallback(process)

        def processing_failed(failure, error_handlers):
            # The failure processor writes to the request.  If the
            # request is already finished we should suppress failure
            # processing.  We don't return failure here because there
            # is no way to surface this failure to the user if the
            # request is finished.
            if request_finished[0]:
                if not failure.check(defer.CancelledError):
                    log.err(failure, "Unhandled Error Processing Request.")
                return

            # If there are no more registered handlers, apply some defaults
            if len(error_handlers) == 0:
                if failure.check(HTTPException):
                    he = failure.value
                    request.setResponseCode(he.code)
                    resp = he.get_response({})

                    for header, value in resp.headers:
                        request.setHeader(ensure_utf8_bytes(header), ensure_utf8_bytes(value))

                    return ensure_utf8_bytes(he.get_body({}))
                else:
                    request.processingFailed(failure)
                    return

            error_handler = error_handlers[0]

            # Each error handler is a tuple of (list_of_exception_types, handler_fn)
            if failure.check(*error_handler[0]):
                d = defer.maybeDeferred(self._app.execute_error_handler,
                                        error_handler[1],
                                        request,
                                        failure)

                return d.addErrback(processing_failed, error_handlers[1:])

            return processing_failed(failure, error_handlers[1:])


        d.addErrback(processing_failed, self._app._error_handlers)
        d.addCallback(write_response).addErrback(log.err, _why="Unhandled Error writing response")
        return server.NOT_DONE_YET
示例#3
0
 def foo(request, bar):
     krequest = IKleinRequest(request)
     relative_url[0] = krequest.url_for('foo', {'bar': bar + 1}, force_external=True)
示例#4
0
 def foo(request, bar):
     krequest = IKleinRequest(request)
     relative_url[0] = krequest.url_for('foo', {'bar': bar + 1})
示例#5
0
文件: app.py 项目: niall-oc/klein
 def branch_f(request, *a, **kw):
     IKleinRequest(request).branch_segments = kw.pop('__rest__', '').split('/')
     return f(request, *a, **kw)
示例#6
0
 def foo(request, bar):
     krequest = IKleinRequest(request)
     relative_url[0] = krequest.url_for('foo', {'bar': bar + 1}, force_external=True)
示例#7
0
 def foo(request, bar):
     krequest = IKleinRequest(request)
     relative_url[0] = krequest.url_for('foo', {'bar': bar + 1})
示例#8
0
文件: app.py 项目: pombreda/klein
 def branch_f(instance, request, *a, **kw):
     IKleinRequest(request).branch_segments = kw.pop(
         '__rest__', '').split('/')
     return _call(instance, f, request, *a, **kw)
示例#9
0
    def render(self, request):
        # Stuff we need to know for the mapper.
        server_name = request.getRequestHostname()
        server_port = request.getHost().port
        if (bool(request.isSecure()), server_port) not in [
                (True, 443), (False, 80)]:
            server_name = '%s:%d' % (server_name, server_port)
        script_name = ''
        if request.prepath:
            script_name = '/'.join(request.prepath)

            if not script_name.startswith('/'):
                script_name = '/' + script_name

        path_info = ''
        if request.postpath:
            path_info = '/'.join(request.postpath)

            if not path_info.startswith('/'):
                path_info = '/' + path_info

        url_scheme = 'https' if request.isSecure() else 'http'
        # Bind our mapper.
        mapper = self._app.url_map.bind(server_name, script_name, path_info=path_info,
            default_method=request.method, url_scheme=url_scheme)
        # Make the mapper available to the view.
        kleinRequest = IKleinRequest(request)
        kleinRequest.mapper = mapper

        # Actually doing the match right here. This can cause an exception to
        # percolate up, which we can catch and render directly in order to
        # save ourselves some legwork.
        try:
            (rule, kwargs) = mapper.match(return_rule=True)
            endpoint = rule.endpoint
        except HTTPException as he:
            request.setResponseCode(he.code)
            return he.get_body({})

        handler = self._app.endpoints[endpoint]

        def _pre_process(res):
            # Standard Twisted Web stuff. Defer the method action, giving us
            # something renderable or printable. Return NOT_DONE_YET and set up
            # the incremental renderer.
            d = defer.maybeDeferred(handler, request, **kwargs)
            return d

        @defer.inlineCallbacks
        def _run_handlers(request):
            for i in self._app._request_handlers:
                yield defer.maybeDeferred(i, request)
            defer.returnValue(None)

        # Run request handler, if present
        if self._app._request_handlers:
            d = _run_handlers(request)
            d.addCallback(_pre_process)
        else:
            d = _pre_process(None)

        def process(r):
            if r == server.NOT_DONE_YET:
                return

            if IResource.providedBy(r):
                while (request.postpath and
                       request.postpath != kleinRequest.branch_segments):
                    request.prepath.append(request.postpath.pop(0))

                return request.render(getChildForRequest(r, request))

            if IRenderable.providedBy(r):
                return flattenString(request, r).addCallback(process)

            if isinstance(r, unicode):
                r = r.encode('utf-8')

            if r is not None:
                request.write(r)

            request.finish()

        d.addCallback(process)
        d.addErrback(request.processingFailed)
        return server.NOT_DONE_YET
示例#10
0
文件: resource.py 项目: alex/klein
    def render(self, request):
        # Stuff we need to know for the mapper.
        server_name = request.getRequestHostname()
        server_port = request.getHost().port
        if (bool(request.isSecure()), server_port) not in [
                (True, 443), (False, 80)]:
            server_name = '%s:%d' % (server_name, server_port)
        script_name = ''
        if request.prepath:
            script_name = '/'.join(request.prepath)

            if not script_name.startswith('/'):
                script_name = '/' + script_name

        path_info = ''
        if request.postpath:
            path_info = '/'.join(request.postpath)

            if not path_info.startswith('/'):
                path_info = '/' + path_info

        url_scheme = 'https' if request.isSecure() else 'http'
        # Bind our mapper.
        mapper = self._app.url_map.bind(server_name, script_name, path_info=path_info,
            default_method=request.method, url_scheme=url_scheme)
        # Make the mapper available to the view.
        kleinRequest = IKleinRequest(request)
        kleinRequest.mapper = mapper

        # Actually doing the match right here. This can cause an exception to
        # percolate up, which we can catch and render directly in order to
        # save ourselves some legwork.
        try:
            (rule, kwargs) = mapper.match(return_rule=True)
            endpoint = rule.endpoint
        except HTTPException as he:
            request.setResponseCode(he.code)
            resp = he.get_response({})

            for header, value in resp.headers:
                request.setHeader(ensure_utf8_bytes(header), ensure_utf8_bytes(value))

            return ensure_utf8_bytes(he.get_body({}))

        # Try pretty hard to fix up prepath and postpath.
        segment_count = self._app.endpoints[endpoint].segment_count
        request.prepath.extend(request.postpath[:segment_count])
        request.postpath = request.postpath[segment_count:]

        # Standard Twisted Web stuff. Defer the method action, giving us
        # something renderable or printable. Return NOT_DONE_YET and set up
        # the incremental renderer.
        d = defer.maybeDeferred(self._app.execute_endpoint,
                                endpoint,
                                request,
                                **kwargs)

        def process(r):
            if IResource.providedBy(r):
                return request.render(getChildForRequest(r, request))

            if IRenderable.providedBy(r):
                return flattenString(request, r).addCallback(process)

            if isinstance(r, unicode):
                r = r.encode('utf-8')

            if r is not None:
                request.write(r)

            request.finish()

        d.addCallback(process)
        d.addErrback(request.processingFailed)
        return server.NOT_DONE_YET
示例#11
0
    def render(self, request):
        # Stuff we need to know for the mapper.
        server_name = request.getRequestHostname()
        server_port = request.getHost().port
        if (bool(request.isSecure()), server_port) not in [
                (True, 443), (False, 80)]:
            server_name = '%s:%d' % (server_name, server_port)
        script_name = ''
        if request.prepath:
            script_name = '/'.join(request.prepath)

            if not script_name.startswith('/'):
                script_name = '/' + script_name

        path_info = ''
        if request.postpath:
            path_info = '/'.join(request.postpath)

            if not path_info.startswith('/'):
                path_info = '/' + path_info

        url_scheme = 'https' if request.isSecure() else 'http'
        # Bind our mapper.
        mapper = self._app.url_map.bind(server_name, script_name, path_info=path_info,
            default_method=request.method, url_scheme=url_scheme)
        # Make the mapper available to the view.
        kleinRequest = IKleinRequest(request)
        kleinRequest.mapper = mapper

        # Make sure we'll notice when the connection goes away unambiguously.
        request_finished = [False]

        def _finish(result):
            request_finished[0] = True

        def _execute():
            # Actually doing the match right here. This can cause an exception
            # to percolate up. If that happens it will be handled below in
            # processing_failed, either by a user-registered error handler or
            # one of our defaults.
            (rule, kwargs) = mapper.match(return_rule=True)
            endpoint = rule.endpoint

            # Try pretty hard to fix up prepath and postpath.
            segment_count = self._app.endpoints[endpoint].segment_count
            request.prepath.extend(request.postpath[:segment_count])
            request.postpath = request.postpath[segment_count:]

            request.notifyFinish().addBoth(_finish)

            # Standard Twisted Web stuff. Defer the method action, giving us
            # something renderable or printable. Return NOT_DONE_YET and set up
            # the incremental renderer.
            d = defer.maybeDeferred(self._app.execute_endpoint,
                                    endpoint,
                                    request,
                                    **kwargs)

            request.notifyFinish().addErrback(lambda _: d.cancel())

            return d

        d = defer.maybeDeferred(_execute)

        def write_response(r):
            if r is not _StandInResource:
                if isinstance(r, unicode):
                    r = r.encode('utf-8')

                if r is not None:
                    request.write(r)

                if not request_finished[0]:
                    request.finish()

        def process(r):
            if IResource.providedBy(r):
                request.render(getChildForRequest(r, request))
                return _StandInResource

            if IRenderable.providedBy(r):
                return flattenString(request, r).addCallback(process)

            return r

        d.addCallback(process)

        def processing_failed(failure, error_handlers):
            # The failure processor writes to the request.  If the
            # request is already finished we should suppress failure
            # processing.  We don't return failure here because there
            # is no way to surface this failure to the user if the
            # request is finished.
            if request_finished[0]:
                if not failure.check(defer.CancelledError):
                    log.err(failure, _why="Unhandled Error Processing Request.")
                return

            # If there are no more registered handlers, apply some defaults
            if len(error_handlers) == 0:
                if failure.check(HTTPException):
                    he = failure.value
                    request.setResponseCode(he.code)
                    resp = he.get_response({})

                    for header, value in resp.headers:
                        request.setHeader(ensure_utf8_bytes(header), ensure_utf8_bytes(value))

                    return ensure_utf8_bytes(he.get_body({}))
                else:
                    request.processingFailed(failure)
                    return

            error_handler = error_handlers[0]

            # Each error handler is a tuple of (list_of_exception_types, handler_fn)
            if failure.check(*error_handler[0]):
                d = defer.maybeDeferred(self._app.execute_error_handler,
                                        error_handler[1],
                                        request,
                                        failure)

                return d.addErrback(processing_failed, error_handlers[1:])

            return processing_failed(failure, error_handlers[1:])


        d.addErrback(processing_failed, self._app._error_handlers)
        d.addCallback(write_response).addErrback(log.err, _why="Unhandled Error writing response")
        return server.NOT_DONE_YET
示例#12
0
 def foo(request, bar):
     krequest = IKleinRequest(request)
     relative_url[0] = krequest.url_for("foo", {"bar": bar + 1}, force_external=True)
示例#13
0
 def foo(request, bar):
     krequest = IKleinRequest(request)
     relative_url[0] = krequest.url_for("foo", {"bar": bar + 1})
示例#14
0
    def render(self, request):
        # Stuff we need to know for the mapper.
        server_name = request.getRequestHostname()
        server_port = request.getHost().port
        if (bool(request.isSecure()), server_port) not in [(True, 443),
                                                           (False, 80)]:
            server_name = '%s:%d' % (server_name, server_port)
        script_name = ''
        if request.prepath:
            script_name = '/'.join(request.prepath)

            if not script_name.startswith('/'):
                script_name = '/' + script_name

        path_info = ''
        if request.postpath:
            path_info = '/'.join(request.postpath)

            if not path_info.startswith('/'):
                path_info = '/' + path_info

        url_scheme = 'https' if request.isSecure() else 'http'
        # Bind our mapper.
        mapper = self._app.url_map.bind(server_name,
                                        script_name,
                                        path_info=path_info,
                                        default_method=request.method,
                                        url_scheme=url_scheme)
        # Make the mapper available to the view.
        kleinRequest = IKleinRequest(request)
        kleinRequest.mapper = mapper

        # Actually doing the match right here. This can cause an exception to
        # percolate up, which we can catch and render directly in order to
        # save ourselves some legwork.
        try:
            (rule, kwargs) = mapper.match(return_rule=True)
            endpoint = rule.endpoint
        except HTTPException as he:
            request.setResponseCode(he.code)
            resp = he.get_response({})

            for header, value in resp.headers:
                request.setHeader(ensure_utf8_bytes(header),
                                  ensure_utf8_bytes(value))

            return ensure_utf8_bytes(he.get_body({}))

        # Try pretty hard to fix up prepath and postpath.
        segment_count = self._app.endpoints[endpoint].segment_count
        request.prepath.extend(request.postpath[:segment_count])
        request.postpath = request.postpath[segment_count:]

        # Standard Twisted Web stuff. Defer the method action, giving us
        # something renderable or printable. Return NOT_DONE_YET and set up
        # the incremental renderer.
        d = defer.maybeDeferred(self._app.execute_endpoint, endpoint, request,
                                **kwargs)

        def process(r):
            if IResource.providedBy(r):
                return request.render(getChildForRequest(r, request))

            if IRenderable.providedBy(r):
                return flattenString(request, r).addCallback(process)

            if isinstance(r, unicode):
                r = r.encode('utf-8')

            if r is not None:
                request.write(r)

            request.finish()

        d.addCallback(process)
        d.addErrback(request.processingFailed)
        return server.NOT_DONE_YET
示例#15
0
 def foo(request, bar):
     krequest = IKleinRequest(request)
     relative_url[0] = krequest.url_for(fullyQualifiedName(foo), {'bar': bar + 1},
         force_external=True)
示例#16
0
    def render(self, request):
        # Stuff we need to know for the mapper.
        server_name = request.getRequestHostname()
        server_port = request.getHost().port
        if (bool(request.isSecure()), server_port) not in [(True, 443),
                                                           (False, 80)]:
            server_name = '%s:%d' % (server_name, server_port)
        script_name = ''
        if request.prepath:
            script_name = '/'.join(request.prepath)

            if not script_name.startswith('/'):
                script_name = '/' + script_name

        path_info = ''
        if request.postpath:
            path_info = '/'.join(request.postpath)

            if not path_info.startswith('/'):
                path_info = '/' + path_info

        url_scheme = 'https' if request.isSecure() else 'http'
        # Bind our mapper.
        mapper = self._app.url_map.bind(server_name,
                                        script_name,
                                        path_info=path_info,
                                        default_method=request.method,
                                        url_scheme=url_scheme)
        # Make the mapper available to the view.
        kleinRequest = IKleinRequest(request)
        kleinRequest.mapper = mapper

        # Make sure we'll notice when the connection goes away unambiguously.
        request_finished = [False]

        def _finish(result):
            request_finished[0] = True

        def _execute():
            # Actually doing the match right here. This can cause an exception
            # to percolate up. If that happens it will be handled below in
            # processing_failed, either by a user-registered error handler or
            # one of our defaults.
            (rule, kwargs) = mapper.match(return_rule=True)
            endpoint = rule.endpoint

            # Try pretty hard to fix up prepath and postpath.
            segment_count = self._app.endpoints[endpoint].segment_count
            request.prepath.extend(request.postpath[:segment_count])
            request.postpath = request.postpath[segment_count:]

            request.notifyFinish().addBoth(_finish)

            # Standard Twisted Web stuff. Defer the method action, giving us
            # something renderable or printable. Return NOT_DONE_YET and set up
            # the incremental renderer.
            d = defer.maybeDeferred(self._app.execute_endpoint, endpoint,
                                    request, **kwargs)

            request.notifyFinish().addErrback(lambda _: d.cancel())

            return d

        d = defer.maybeDeferred(_execute)

        def write_response(r):
            if r is not _StandInResource:
                if isinstance(r, unicode):
                    r = r.encode('utf-8')

                if r is not None:
                    request.write(r)

                if not request_finished[0]:
                    request.finish()

        def process(r):
            if IResource.providedBy(r):
                request.render(getChildForRequest(r, request))
                return _StandInResource

            if IRenderable.providedBy(r):
                return flattenString(request, r).addCallback(process)

            return r

        d.addCallback(process)

        def processing_failed(failure, error_handlers):
            # The failure processor writes to the request.  If the
            # request is already finished we should suppress failure
            # processing.  We don't return failure here because there
            # is no way to surface this failure to the user if the
            # request is finished.
            if request_finished[0]:
                if not failure.check(defer.CancelledError):
                    log.err(failure,
                            _why="Unhandled Error Processing Request.")
                return

            # If there are no more registered handlers, apply some defaults
            if len(error_handlers) == 0:
                if failure.check(HTTPException):
                    he = failure.value
                    request.setResponseCode(he.code)
                    resp = he.get_response({})

                    for header, value in resp.headers:
                        request.setHeader(ensure_utf8_bytes(header),
                                          ensure_utf8_bytes(value))

                    return ensure_utf8_bytes(he.get_body({}))
                else:
                    request.processingFailed(failure)
                    return

            error_handler = error_handlers[0]

            # Each error handler is a tuple of (list_of_exception_types, handler_fn)
            if failure.check(*error_handler[0]):
                d = defer.maybeDeferred(self._app.execute_error_handler,
                                        error_handler[1], request, failure)

                return d.addErrback(processing_failed, error_handlers[1:])

            return processing_failed(failure, error_handlers[1:])

        d.addErrback(processing_failed, self._app._error_handlers)
        d.addCallback(write_response).addErrback(
            log.err, _why="Unhandled Error writing response")
        return server.NOT_DONE_YET