util.redirect() returns wrong SERVER_RETURN status value

Details

Description

The util.redirect() function ends with:

raise apache.SERVER_RETURN, apache.OK

Although this will work when used in a handler run in the response/content handler phase, it will not always provide the desired result in a phase such as authenhandler where returning apache.OK actually means that the handler sucessfully authenticated the user.

One particular scenario that can result in undesirable behaviour is where a URL matches to a directory and Apache decides to iterate over files listed in DirectoryIndex trying to find an actual file. As it checks for each file, it will trigger any authenhandler. If the authenhandler decides it wants to redirect using util.redirect(), a status of apache.OK is being returned. All this does is make Apache think that authentication was successful and it ignores the fact that a redirection was being requested. The redirection only occurs when it gets to the last file listed in DirectoryIndex and it gives up, or it found one of the files. The desired result should be that it should stop looking through files immediately the redirection occurs.

To solve this problem and because util.redirect() is generating a complete response anyway, it should be returning apache.DONE and not apache.OK. Thus it should be using:

raise apache.SERVER_RETURN, apache.DONE

By making this change, it will be safe to use util.redirect() in phases earlier than the response/content handler phase. This is not just because of the redirection issue described above, but is also because returning apache.OK as it does now doesn't actually stop any later phase from running, so a response/content handler would still run if one exists, with the content being appended to the content already generated by the util.redirect() function. Even if the util.redirect() was used in a response/content handler, without this change any stacked handlers not yet executed for the phase may still be run.