twisted / nevow

Web Application Construction Kit

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IResource compatibility layer breaks on leaf resources with pre/postpath manipulation

exarkun opened this issue · comments

If an IResource is placed into a NevowSite resource hierarchy and there is a resource beneath it with isLeaf = True and which also shuffles segments between prepath and postpath then OldResourceAdapter mangles prepath and postpath in a way that ruins them as information letting the leaf resource determine what the request was and where it lives in the resource hierarchy during rendering.

This exact combination of behavior is what you get if you try to use twisted.web.guard inside a Nevow resource hierarchy. Guard provides HTTPAuthSessionWrapper which returns isLeaf = True children by way of its use of twisted.web.util.DeferredResource. It also takes the last element of prepath and moves it back to the beginning of postpath to "unconsume" one segment of the URL. The ideis that HTTPAuthSessionWrapper is a transparent wrapper around a sub-tree of the resource hierarchy and does not represent any resource in the hierarchy itself.

The offending Nevow code can be seen here:

    def renderHTTP(self, ctx):
        request = inevow.IRequest(ctx)
        if self.real_prepath_len is not None:
            request.postpath = request.prepath[self.real_prepath_len:]
            del request.prepath[self.real_prepath_len:]
        result = defer.maybeDeferred(self.original.render, request).addCallback(
            self._handle_NOT_DONE_YET, request)
        return result

Unfortunately there are no unit tests for this behavior and the comment for real_prepath_len doesn't clearly (to me) explain why this behavior is implemented or what problem it solves.

My best guess is that the intent is the restoration of prepath and postpath to their values at the time the leaf was encountered. The implementation is correct as long as the two lists aren't mutated outside of the control of Nevow but it fails if they are.