Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Apache: Users

RewriteRule in neither "foo/.htaccess" nor ".htaccess" can match http://example.com/.../foo

 

 

Apache users RSS feed   Index | Next | Previous | View Threaded


ms419 at freezone

Nov 24, 2009, 12:49 PM

Post #1 of 6 (750 views)
Permalink
RewriteRule in neither "foo/.htaccess" nor ".htaccess" can match http://example.com/.../foo

I'm struggling a bit with this mod_rewrite rule,

RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule . %{REQUEST_FILENAME}.html

My goal is, when someone requests http://example.com/.../foo, to respond
with "foo.html", if it exists

I originally tried doing this with MultiViews, but MultiViews won't
respond with "foo.html" if "foo" exists, and I have a case where I want,

* http://example.com/.../foo to respond with "foo.html",
* http://example.com/.../foo/ to respond with "foo/index.html",
* http://example.com/.../foo/bar to respond with "foo/bar.html"

I originally posted about how to do this with MultiViews here,
http://thread.gmane.org/gmane.comp.apache.user/87707

Aside from patching mod_negotiation, I think my only option is to use
mod_rewrite?

This %{REQUEST_FILENAME}.html rule is inferior to MultiViews because it
doesn't consider the Accept: request header - but it's good enough for
my case

My first struggle was with DirectorySlash - in server context, this
%{REQUEST_FILENAME}.html rule works, even with mod_dir enabled - but
in .htaccess context, mod_dir redirects requests for
http://example.com/.../foo to http://example.com/.../foo/ before the
rule can respond with "foo.html" instead

I set "DirectorySlash Off" to get around this

My second and current struggle is that in one case, the directory "foo"
already contains a .htaccess with,

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php

This rule works, before and after I added the %{REQUEST_FILENAME}.html
rule and "DirectorySlash Off" to a .htaccess in the parent directory -
but the %{REQUEST_FILENAME}.html rule doesn't work in this case -
requests for http://example.com/.../foo don't respond with "foo.html" :
(

I found that if I comment all the "Rewrite" statements out of
"foo/.htaccess", then the %{REQUEST_FILENAME}.html rule works again - I
guess any "Rewrite" directive in a .htaccess disables rules in .htaccess
files in parent directories?

So I tried copying the %{REQUEST_FILENAME}.html rule to "foo/.htaccess",
but this still doesn't work - I think "RewriteRule ^$ ..." in
"foo/.htaccess" matches http://example.com/.../foo/, but doesn't match
http://example.com/.../foo

So it seems there's no way for a mod_rewrite rule in .htaccess context
to match http://example.com/.../foo - with "RewriteRule .
%{REQUEST_FILENAME}.html" in the parent directory, and "RewriteRule ^$
%{REQUEST_FILENAME}.html" in "foo/.htaccess", the rule in
"foo/.htaccess" disables the rule in the parent directory, without
possibly matching http://example.com/.../foo

Can we please have on or the other? : )

Either rules in "foo/.htaccess" can match http://example.com/.../foo or
rules in the parent directory can match http://example.com/.../foo -
currently it seems neither is true : (

I checked that this is still the case with trunk revision 883548

I used this httpd.conf,
http://www.sfu.ca/~jdbates/tmp/apache/200911240/httpd.conf

- and these .htaccess files,
http://www.sfu.ca/~jdbates/tmp/apache/200911240/www.tgz

I didn't have any more success by adding "RewriteOptions inherit"

---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe [at] httpd
" from the digest: users-digest-unsubscribe [at] httpd
For additional commands, e-mail: users-help [at] httpd


aw at ice-sa

Nov 24, 2009, 2:08 PM

Post #2 of 6 (723 views)
Permalink
Re: RewriteRule in neither "foo/.htaccess" nor ".htaccess" can match http://example.com/.../foo [In reply to]

Jack Bates wrote:
> I'm struggling a bit with this mod_rewrite rule,
>
I am a bit intimidated by your detailed explanation and the level of
expertise required to fully understand your requirements, never mind
finding a solution. But reading your post in diagonals gives me the
feeling that maybe the sum of your requirements is just a bit too much
to be covered by generic modules like mod_rewrite et al., which after
all are generic tools and not specifically designed to cover all
possible cases and countercases one could come up with.
It seems like what you want is something like
/foo to deliver /foo.html
except if /foo really exists and is a directory, then you would want
/foo/index.html to be delivered
except if the directory /foo contains a .htaccess, in which case you
want the .htaccess-contained rewrite rules to apply
except if /foo is a sub-directory of another directory already
containing a .htaccess with rewrite rules in it, in which case these
should apply too
I may be jesting a bit, but don't you think this is a bit much to ask ?

In a case like this, maybe it is the layout of the site that needs to be
revisited, or an ad-hoc custom fixup module (mod_perl ?) may be the
second choice.
Purely personal opinion of course.


---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe [at] httpd
" from the digest: users-digest-unsubscribe [at] httpd
For additional commands, e-mail: users-help [at] httpd


ms419 at freezone

Nov 24, 2009, 4:09 PM

Post #3 of 6 (711 views)
Permalink
Re: RewriteRule in neither "foo/.htaccess" nor ".htaccess" can match http://example.com/.../foo [In reply to]

> Jack Bates wrote:
> > I'm struggling a bit with this mod_rewrite rule,
>
> I am a bit intimidated by your detailed explanation and the level of
> expertise required to fully understand your requirements, never mind
> finding a solution. But reading your post in diagonals gives me the
> feeling that maybe the sum of your requirements is just a bit too much
> to be covered by generic modules like mod_rewrite et al., which after
> all are generic tools and not specifically designed to cover all
> possible cases and countercases one could come up with.
> It seems like what you want is something like
> /foo to deliver /foo.html
> except if /foo really exists and is a directory, then you would want
> /foo/index.html to be delivered
> except if the directory /foo contains a .htaccess, in which case you
> want the .htaccess-contained rewrite rules to apply
> except if /foo is a sub-directory of another directory already
> containing a .htaccess with rewrite rules in it, in which case these
> should apply too
> I may be jesting a bit, but don't you think this is a bit much to ask ?

Thanks Andre - I take you point : )

Just for clarification, I want,

* /foo/ to deliver /foo/index.html, or whatever it would naturally deliver
* /foo to deliver /foo.html always

---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe [at] httpd
" from the digest: users-digest-unsubscribe [at] httpd
For additional commands, e-mail: users-help [at] httpd


covener at gmail

Nov 24, 2009, 6:58 PM

Post #4 of 6 (711 views)
Permalink
Re: Re: RewriteRule in neither "foo/.htaccess" nor ".htaccess" can match http://example.com/.../foo [In reply to]

On 11/24/09, Jack Bates <ms419 [at] freezone> wrote:
> * /foo/ to deliver /foo/index.html, or whatever it would naturally deliver
> * /foo to deliver /foo.html always

IIUC, your problem boils down to:

/.htaccess has your desired behavior
/foo/.htaccess has some undesired, incompatible catch-all behavior

Sounds like you'd be a customer for the enhancement suggested here:
https://issues.apache.org/bugzilla/show_bug.cgi?id=39313

Which makes the inherited rules run before the more specific rules. At
least you'd have a fighting chance with the other order.


--
Eric Covener
covener [at] gmail

---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe [at] httpd
" from the digest: users-digest-unsubscribe [at] httpd
For additional commands, e-mail: users-help [at] httpd


ms419 at freezone

Nov 25, 2009, 9:44 AM

Post #5 of 6 (705 views)
Permalink
Re: RewriteRule in neither "foo/.htaccess" nor ".htaccess" can match http://example.com/.../foo [In reply to]

> On 11/24/09, Jack Bates <ms419 <at> freezone.co.uk> wrote:
> > * /foo/ to deliver /foo/index.html, or whatever it would naturally
> deliver
> > * /foo to deliver /foo.html always
>
> IIUC, your problem boils down to:
>
> /.htaccess has your desired behavior
> /foo/.htaccess has some undesired, incompatible catch-all behavior

Almost -

/.htaccess has one desired behaviour,
/foo/.htaccess has another, also desired, compatible behaviour

In my case I don't think it would matter which rules took precedence

The trouble is, when there is any "Rewrite" directive in /foo/.htaccess,
I can't get the rules from /.htaccess to apply - either by using
"RewriteOptions inherit" or by copying the rules from /.htaccess
to /foo/.htaccess

Here's a shorter, hopefully clearer example,

Contents of /.htaccess,

> DirectorySlash Off
>
> RewriteEngine On
> RewriteCond %{REQUEST_FILENAME}.html -f
> RewriteRule . %{REQUEST_FILENAME}.html

With this configuration and no "Rewrite" directives in /foo/.htaccess,
requests for http://example.com/.../foo successfully respond
with /foo.html

- but if I make the contents of /foo/.htaccess,

> RewriteEngine On
> RewriteOptions inherit

Now requests for http://example.com/.../foo no longer respond
with /foo.html : (

So the fact that there are "Rewrite" directives in /foo/.htaccess is
interfering with requests for http://example.com/.../foo, but the rules
in /foo/.htaccess can't match requests for http://example.com/.../foo
(although they can match requests for http://example.com/.../foo/)

I think it's currently impossible for *any* rule in /foo/.htaccess to
match http://example.com/.../foo

I think it should be one or the other - either it should be possible for
a rule in /foo/.htaccess to match http://example.com/.../foo, or rules
in /foo/.htaccess shouldn't disable rules in /.htaccess

---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe [at] httpd
" from the digest: users-digest-unsubscribe [at] httpd
For additional commands, e-mail: users-help [at] httpd


aw at ice-sa

Nov 25, 2009, 11:16 AM

Post #6 of 6 (702 views)
Permalink
Re: Re: RewriteRule in neither "foo/.htaccess" nor ".htaccess" can match http://example.com/.../foo [In reply to]

Jack Bates wrote:
...
Hi again.
I am not saying here that you are necessarily wrong, or that there is
not a good justification to what you are trying to do, or to what you
asserted at the end of the previous post.

But one thing you should be aware of, is that when you place
instructions in a .htaccess file, you are in fact asking Apache
to walk down the whole directory tree, applying all its configuration
rules level by level as it does so, until it gets to the level of the
directory where it finds the first .htaccess file.
Then, because this .htaccess rewrites the URL, you are basically telling
Apache to throw away all the result of its previous work, and to start
again at the top with the new URL. Then, in your case and assuming
everything works down to that level, it will end up at the level of the
subdirectory, and find again a .htaccess with rewrite rules. So it will
again rewrite the URL, and again restart at the top.
In the best of cases, that is rather inefficient.
In the less best case, you have missed an intermediate transformation
somewhere, which is leading to a series of rules being applied, that is
different from what you expect.

My personal point of view is that one should avoid .htaccess files if
one can, which is most of the time when one has access and can modify
the main server configuration files, as you seem to be able to.
.htaccess should be reserved for cases where one does not have access to
the server condiguration, and only to one's own directory for instance.

I have not followed your rules step by step, and do not really wish to,
and do not have access to your full configuration sequence of directives
anyway. But given that Apache is being used on hundreds of thousands of
sites, many of them using mod_rewrite and .htaccess files, and
apparently seems to be doing fine most of the time, my current odds
would be in the order of magnitude Apache 10 / Jack 1.

It may be so for instance that what is interpreted the first way around
as the request filename, is no longer considered as such if there is a
subdirectory below the current one. Or some other such apparently
obscure side-effect.

So anyway, if it does not work the way you want when you have a
hierarchical set of rewrite rules in .htaccess files, it may be worth
asking yourself if it is not possible to remove one such level and move
the corresponding rules into the main part of the configuration, which
would probably be more efficient anyway.




---------------------------------------------------------------------
The official User-To-User support forum of the Apache HTTP Server Project.
See <URL:http://httpd.apache.org/userslist.html> for more info.
To unsubscribe, e-mail: users-unsubscribe [at] httpd
" from the digest: users-digest-unsubscribe [at] httpd
For additional commands, e-mail: users-help [at] httpd

Apache users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.