[ http://issues.apache.org/jira/browse/MODPYTHON-129?page=all ]
Graham Dumpleton reassigned MODPYTHON-129: ------------------------------------------ Assign To: Graham Dumpleton > HandlerDispatch doesn't treat OK/DECLINED result properly for all phases. > ------------------------------------------------------------------------- > > Key: MODPYTHON-129 > URL: http://issues.apache.org/jira/browse/MODPYTHON-129 > Project: mod_python > Type: Bug > Components: core > Versions: 3.2 > Reporter: Graham Dumpleton > Assignee: Graham Dumpleton > > Todays daily bug report, or is it? ;-) > The Python*Handler documentation says: > """Multiple handlers can be specified on a single line, in which case they > will be called sequentially, from left to right. Same handler directives can > be specified multiple times as well, with the same result - all handlers > listed will be executed sequentially, from first to last. If any handler in > the sequence returns a value other than apache.OK, then execution of all > subsequent handlers is aborted.""" > That is, no matter which phase is being processed, mod_python will stop > processing them if a value other than OK is returned. > Problem is that this isn't how Apache itself treats the result from handlers. > Apache actually implements two different ways for dealing with the result > from the handlers. Which is used depends on which processing phase is > occuring. This is all specified by the Apache magic macro code: > AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, > (request_rec *r), (r), DECLINED) > AP_IMPLEMENT_HOOK_RUN_FIRST(int,map_to_storage, > (request_rec *r), (r), DECLINED) > AP_IMPLEMENT_HOOK_RUN_FIRST(int,check_user_id, > (request_rec *r), (r), DECLINED) > AP_IMPLEMENT_HOOK_RUN_FIRST(int,auth_checker, > (request_rec *r), (r), DECLINED) > AP_IMPLEMENT_HOOK_RUN_ALL(int,access_checker, > (request_rec *r), (r), OK, DECLINED) > AP_IMPLEMENT_HOOK_RUN_FIRST(int,type_checker, > (request_rec *r), (r), DECLINED) > AP_IMPLEMENT_HOOK_RUN_ALL(int,fixups, > (request_rec *r), (r), OK, DECLINED) > What this gobblegook expands to are loops which will stop processing handlers > based on the result. > For the AP_IMPLEMENT_HOOK_RUN_ALL macro, all handlers in the phase will be > run unless one returns something other than OK or DECLINED. Returning OK > means that it did something and it worked okay. Returing DECLINED means that > it didn't do anything at all. In both these cases, it still goes onto the > next handler in that phase. After that it will go onto the next phase. > Returning an error will cause appropriate error response to go back to client > with any other handlers in the phase, as well as later phases being skipped. > Returning DONE is much like returning an error but Apache interprets it as > meaning a complete response was constructed and that it doesn't have to > generate any response. > For the AP_IMPLEMENT_HOOK_RUN_FIRST macro, all handlers will be run only if > they all return DECLINED. In other words, if a handler returns OK it will > skip the following handlers in that phase and then move onto the next phase. > Returning an error or DONE is like above. > In the case of mod_python, what it does doesn't fit into either. It is closer > to behaving like the AP_IMPLEMENT_HOOK_RUN_ALL macro except that it stops > processing further handlers in the phase if DECLINED is returned. > As to what problems this causes, imagine you had registered multiple > authentication handlers which supported different authentication mechanisms. > This is the case where AP_IMPLEMENT_HOOK_RUN_FIRST macro is used. The idea > is that each authentication handler would check the value associated with the > AuthType directive to determine if it should do anything. If it was not the > AuthType it implements, if it were a C based handler module, it would > returned DECLINED to indicate it hadn't done anything and that the next > handler should instead be tried. Each handler would thus be called until one > handler says that is for me, says the user is valid and returns OK or returns > an error rejecting it. > If you wanted to write these multiple authentication handlers in Python you > can't do it. This is because the way mod_python works, if you return DECLINED > it would actually skip the remainder of the mod_python declared handlers > whereas you still want them to be executed. Apache would still execute any > other C based handlers in the phase though. The only way to get mod_python to > execute later mod_python handlers in the phase is to return OK, but if you do > that and it happens to be the last handler in the mod_python list of > handlers, it will return OK to Apache and Apache will then think a handler > successfully handled it and not then execute any subsequent C based handlers > in that phase. > There are going to be other sorts of problems with phases implemented using > AP_IMPLEMENT_HOOK_RUN_ALL as well, as a handler that validly returns DECLINED > to say it didn't do anything will cause mod_python to skip later mod_python > handlers as well. If it were only C based handlers, that wouldn't be the case. > In summary, it doesn't work how it probably should. > Note that the above relates to phases other than content handler. Still have > to work out what Apache does for content handler phase when there are > multiple handlers for the phase. > No one has probably noticed these problems as no one seems to use mod_python > in a serious way for implementing these other phases, simply using mod_python > as a jumping off point for content handlers. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira