views:

196

answers:

3

I've written a module that sets Apache environment variables to be used by mod-rewrite. It hooks into ap_hook_post_read_request() and that works fine, but if mod-rewrite matches a RewriteRule then it makes a second call to my request handler with the rewritten URL. This looks like a new request to me in that the environment variables are no longer set and therefore I have to execute my (expensive) code twice for each hit.

What am I doing wrong, or is there a work around for this?

Thanks

+1  A: 

You can use the [NS] modifier on a rule to cause it to not be processed for internal subrequests (the second pass you're seeing is an internal subrequest).

chaos
Thanks for the response. Unfortunately, that doesn't seem to work for me. I also tried setting an env var in the rule (like [E=DONE:YES]) and detect it in my request handler, but no go.
Dave
@Dave: Did you try `REDIRECT_DONE` instead of `DONE`?
Gumbo
Thanks, just tried that. Still no go. I also tried prefixing the name w/HTTP_ (e.g. HTTP_REQUEST_DONE) as I found that in some thread. You'd think that mod-rewrite (or Apache) would preserve the environment during the subrequest(s), or set something I could look at to say it was a subrequest.
Dave
+1  A: 

As I understand it, the NS flag (suggested in another answer) on a rule makes it evaluate as "if I am being called a second time, ignore me". The trouble is, by then it's too late since the hook has already been called. I believe this will be a problem no matter what you do in mod_rewrite. You can detect the second request, but I don't know of any way to prevent the second request.

My best suggestion is to put the detection in your handler before your (expensive) code and exit if it's being run a second time. You could have mod_rewrite append something to the URL so you'd know when it's being called a second time.

However...

If your (expensive) code is being called on every request, it's also being called on images, css files, favicons, etc. Do you really want that? Or is that possibly what you are seeing as the second call?

bmb
+1  A: 

Thanks a bunch, I did something similar to what bmb suggested and it works! But rather than involving mod-rewrite in this at all, I added a "fake" request header in my module's request handler, like so:

apr_table_set(r->headers_in, "HTTP_MY_MODULE", "yes");

Then I could detect it at the top of my handler on the second rewritten request. Turns out that even though mod-rewrite (or Apache?) doesn't preserve added env or notes variables (r->subprocess_env, r->notes) in a subrequest, it does preserve added headers.

As for my expensive code getting called on every request, I have a configurable URL suffix/extension filter in the handler to ignore image, etc requests.

Dave