Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

regex to match a series of file types in .htaccess

this is going to be a silly question I guess but I don't see what is going on here. I want to match a certain set of URIs via a regex in an .htaccess file.

I want the following

  • All files that don't contain a .
  • all files ending on .htm / .html
  • all files ending on .php

So:

^[^.]+$

works to match all files with no dot in the URI.

\.html?$

matches all .html / .htm files

(^[^.]+$)|(\.html?$)

seems to work combining both

(^[^.]+$)|(\.html?$)|(\.php$)

fails to combine things with the match files ending on php case. test.jpg for example matches now while it should not.

I must be missing something obvious. What is it? Thanks.

Update: here is the entire context I was using:

### REWRITE RULES ###
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (^[^.]+$)|(\.html?$)|(\.php$) bootstrap.php [L,QSA]

bootstrap.php contains:

echo "testing bootstrap";

Querying a non existing .jpg

http://localhost/test.jpg

gives me this output:

testing bootstrap
...

Update 2:

After testing the first answer below I found that using the simple:

RewriteRule \.php$ bootstrap.php [L,QSA]

fails in the same way as the above. It matches test.jpg. There is nothing crazy in the server configuration or .htaccess file though... This is all there is in the .htaccess file except what I posted already:

AddType application/x-httpd-php .html
AddType application/x-httpd-php .xml
DirectoryIndex index.php
ErrorDocument 404 /errors/404.php

Answer: (Couldn't anwer my own question for 8 more hours...)

Thanks everyone for helping me out.
Special thanks to @mario who helped me solve this by his comment below.
It was a silly question indeed. Here is what was happening:

rewrite.log:

strip per-dir prefix: D:/Web_Root/test.jpg -> test.jpg
applying pattern '\.php$' to uri 'test.jpg'
pass through D:/Web_Root/test.jpg
strip per-dir prefix: D:/Web_Root/errors/404.php -> errors/404.php
applying pattern '\.php$' to uri 'errors/404.php'
RewriteCond: input='D:/Web_Root/errors/404.php' pattern='!-d' => matched
rewrite 'errors/404.php' -> 'bootstrap.php'
...

So the problem was that my 404 document ended on *.php which was why *.jpg matched for the not found file. Ah Bats, I would have searched this one for a long time...

So this does it:

RewriteRule ([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]

Well, the complete question's answer is:

RewriteRule (^[^.]+$)|(\.html?$)|([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]

Again: Thanks people.

like image 843
C.O. Avatar asked Nov 13 '22 23:11

C.O.


1 Answers

[Ok, this was not the specific solution here, but I'll make it a faux answer.]

When mod_rewrite rules go wrong, it sometimes helps to enable the RewriteLog. It needs to be configured in the httpd.conf or VirtualHost section and thus is a bit effort. But there Apache will list the order and processing actions it performs and the URL. This can be helpful to see if the regex is understood by Apache and does behave as it should.

Note that it can sometimes remain empty - if the actual error source are Alias and Redirect rules or even FileMatch sections. In this case the error.log or even just the access.log might contain some hints however.

If all fails, you might have luck with temporarily enabling Nanoweb instead of Apache. It comes with a similar mod_rewrite implementation, which however uses PHPs preg_match PCRE backend. (Not telling why I know that.)

like image 106
mario Avatar answered Dec 21 '22 08:12

mario