On Sun 12 Oct 2008, André Warnier wrote:
> In an attempt at being clever, I put the following code in the
> handler :
>
>      unless ($r->is_initial_req) {
>          if (defined $r->prev) {
>              # we are in a subrequest.  Just copy user from main
> request. $r->user( $r->prev->user );
>          }
>          # Also disable authorization phase
>          $r->set_handlers(PerlAuthzHandler => undef);
>          return OK;
>      }

You have to distinguish between subrequests and internal redirects. The 
former result from $r->lookup_uri, $r->lookup_file or similar (there 
are a few more such functions in the C API) and internal redirects that 
result from $r->internal_redirect (internal_fast_redirect() is not as 
the name suggests an internal redirect but simply overrides the current 
request). Subrequests are used for example by mod_rewrite, mod_include, 
mod_negotiation to look for some characteristics of a document and 
perhaps pull it in (run() it). Internal redirects are used in mod_cgi 
when the CGI output indicates a status 200 (HTTP_OK) but also contains 
a Location header. But the main usage of internal redirects is the 
ErrorDocument.

Now, is_initial_req() checks if the current $r is the result of a 
subrequest or the result of a internal redirect and returns false if 
so. prev() returns the parent request if the current $r is the result 
of an internal redirect and main() returns the main request if the 
current $r is a subrequest. So, your code checks only for internal 
redirects (ErrorDocument).

Now, have a look at httpd-2.x.y/server/request.c around line 170. You'll 
see this piece of code:

    /* Skip authn/authz if the parent or prior request passed the
     * authn/authz,
     * and that configuration didn't change (this requires
     * optimized _walk()
     * functions in map_to_storage that use the same merge results given
     * identical input.)  If the config changes, we must re-auth.
     */
    if (r->main && (r->main->per_dir_config == r->per_dir_config)) {
        r->user = r->main->user;
        r->ap_auth_type = r->main->ap_auth_type;
    }
    else if (r->prev && (r->prev->per_dir_config == r->per_dir_config)) 
{
        r->user = r->prev->user;
        r->ap_auth_type = r->prev->ap_auth_type;
    }
    else {
        switch (ap_satisfies(r)) {
        case SATISFY_ALL:
        case SATISFY_NOSPEC:
            if ((access_status = ap_run_access_checker(r)) != 0) {
                return decl_die(access_status, "check access", r);
    ...

You see, you are not the first who had had the idea of reusing an 
established identity. If your subreq or internal redirect hits the same 
Location or Directory container the AAA phases are completely skipped.
Maybe this is enough optimization if you shift a few directives around 
in your httpd.conf.

If not, the code above shows you how to do it. But you must ask yourself 
if it really is valid to reuse the identity. I believe, you can safely 
inherit the identity from $r->main or $r->prev but you must not skip 
the other 2 A's. If you can't it would mean you have one realm of 
identities for the main request and another for the subreq. That, I'd 
say, is a configuration error.

> The idea being that if we are in a sub-request, there is no point in
> authenticating/authorizing it again, since the main request should
> already do that, right ?  Optimisation..
>
> Now the above works very nicely, except in the case where, before
> this handler gets called, there is an intervention by mod_rewrite. It
> seems as if mod_rewrite makes the above fail, even when the rewrite
> condition does not apply and the URL is considered as a
> "pass-through".
>
> I suspect that it is because mod_rewrite, no matter what, invoques
> the original (or modified) URL as a sub-request of the original
> request. This would cause the above to fail, because in such a case,
> the above conditional code would be invoked, but there is no
> $r->prev->user to be copied.

mod_rewrite doesn't make subrequests if not asked to. I know only of 2 
ways to have mod_rewrite perform a subreq: %{LA-U:variable} 
and %{LA-F:variable} in a RewriteCond.

Torsten

--
Need professional mod_perl support?
Just hire me: [EMAIL PROTECTED]

Reply via email to