mod_rewrite but skip a directory - mod-rewrite

I'm attempting to avoid urls like this one:
images/
or
images/valid-filename.png
or
images/invalid-filename.png
from being rewritten
and I've checked other example questions like .htaccess mod_rewrite on root directory but need it to skip all other directories and .htaccess mod_rewrite exemptions and this one https://stackoverflow.com/questions/7209746/can-mod-rewrite-skip-a-folder but I've not managed to get the rules to achieve what I'm after.
Here is what I have right now:
# Enable URL Rewriting
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(scripts|styles|images)(/.*|$) - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/robots.txt
RewriteCond %{REQUEST_URI} !=/favicon.ico
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# This solved the problem
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RewriteCond %{REQUEST_URI} !images/.* [NC]
RewriteRule ^(.*)$ index.php [L,QSA]
</IfModule>
If I navigate to www.site.com/images/, I get redirected to www.site.com
If I navigate to www.site.com/images/invalid-filename.png, I get redirected to www.site.com
but www.site.com/images/valid-filename.png loads correctly.
Could someone help to explain how to achieve the rewrite behaviour described above?
Many thanks

Try adding this RewriteCond: RewriteCond %{REQUEST_URI} !images/.* [NC]
It will check whether the URI begins with images/ and if it does, the rule will not be met.

Related

Redirect based on the beginning of the path

I'm building a Laravel project. The project itself has a "legacy" version with a whole different structure. It's logged that some users are trying to access a file that is not found in the new environment.
For a quick "fix", we want to redirect paths like
/media/22044/blablabla.pdf to /en/press
The quick solution is to use
Redirect 301 /media/22044/blabla.pdf /en/press
But we want the path behind /media/ to be dynamic.
I'm new with .htaccess stuff.
Is there a way to do it?
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
# this one works, but not dynamic
#Redirect 301 /media/2336/blabla.pdf /en/press
# failed experiments
#Redirect 301 (\/media)(.*)$ /en/press
#Redirect 301 ^/media/(.*)$ /en/press
#RewriteRule ^/media/(.*) /en/press [R=301,NC,L]
Redirect 301 /media/(.*) /en/press
</IfModule>
You need to use a mod_rewrite RewriteRule directive (not Redirect) before your existing rewrite.
For example:
RewriteEngine on
# Redirect "/media/<anything>" to "/en/press"
RewriteRule ^media/ /en/press [R=301,L]
# Rewrite all requests to the "/public" subdirectory
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
The Redirect directive uses simple prefix-matching, not a regex. But is also processed later in the request.
And note that the URL-path matched by the RewriteRule pattern does not start with a slash, unlike the Redirect directive.
With your shown samples and attempts please try following .htaccess rule file. Please make sure to clear your browser cache before testing your URLs.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public [NC]
RewriteRule ^(.*)/?$ public/$1 [L,NC]
###new redirect here...
RewriteCond %{THE_REQUEST} \s/.*/media/22044/blablabla\.pdf\s [NC]
RewriteRule ^ /en/press? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en/press)/?$ media/22044/blablabla\.pdf [NC,L]
</IfModule>

how to allow /.well-known/security.txt in htaccess

I want to whitelist this file only in .well-known directory .
My htaccess file
Options -Indexes
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
<IfModule mod_rewrite.c>
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]
</IfModule>
my attempts
<Files .well-known/security.txt>
Allow from all
Satisfy Any
</Files>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(public|.well-known/security.txt)
RewriteRule ^(.*)$ public/$1 [L]
Conclusion !
I just want to whitelist security.txt file only in .well-known directory
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
This condition is in error since the REQUEST_URI server variable always starts with a slash, so the expression !^public is always successful.
(From this I assume you must have another .htaccess file in the /public subdirectory, otherwise you would get a rewrite loop.)
Once you realise this then you can modify the rule in the way you had tried. For example:
RewriteCond %{REQUEST_URI} !^/(public|\.well-known/security\.txt$)
RewriteRule ^(.*)$ public/$1 [L]
HOWEVER, your other rule blocks all requests for physical files/directories that start with a dot, so the request will still be blocked (with a 403 Forbidden). This rule is also in the wrong place for other requests (it needs to be before the rewrite to the /public subdirectory).
You are better off making an exception as a separate rule at the start of the file instead. For example, try the following instead:
Options -Indexes
RewriteEngine on
# Prevent further processing for special files
RewriteRule ^\.well-known/security\.txt$ - [L]
# Block access to all dot-files
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule (^|/)\. - [F]
# Rewrite request to "/public" subdirectory
RewriteCond %{REQUEST_URI} !^/public
RewriteRule (.*) public/$1 [L]
The <IfModule> wrapper on that one rule was superfluous.

change document root with .htaccess internal redirect not working properly

Hello my fellow developers,
i need to change my document root some specific folder which holds the source code of my laravel project on a shared hosting, since my hosting plan dont let me change default document root so i cannot change my default index so i want to have to redirect it using .htaccess
for far i have been able to internally redirect with the following code
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*)$ master/project/public/index.php
doing this i am able to redirect to desired folder, but for some reason it is not working for assets, i keep getting 404 on all the assets
master/project/public/css/[all styles]
master/project/public/js/[all scritps]
master/project/public/images/[all pictures]
master/project/public/fonts/[all fonts]
how can i achieve this without having to change urls,
internal redirect is working but i cannot figure out why all of my assets are returning 404
Try this
i m using shared hosting and this i m using for redirect asset to public dir
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
#all request to public dir
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
To redirect all request to public
#all request to public dir
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
so i found solution to my problem,
this solution is what i ended up with.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteCond %{REQUEST_URI} !master/project/public/
RewriteRule (.*) /master/project/public/$1 [L]
this way you can change the default root of the your hosting using .htaccess file. hopefully it is helpful for everybody new to .htaccess

AJAX rewrite rule for directories

I'm trying to write a rewrite rule in addition to wordpress's :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
I would not like everything to redirect to the main page. I have multiple sub-directories which need to be redirected too : http://www.example.com/sub1 and http://www.example.com/sub2. I'm doing this so my content can be loaded via Ajax.
I thought this would simply be
RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]
Which I placed in the block here:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]
RewriteRule . /index.php [L]
</IfModule>
Perhaps with wordpress you must use wp_rewrite_rule? I figured I could mess with the .htaccess file, get my rule to work, then move it over to functions.
any help would be appreciated.
Thanks.
UPDATE:
I've also tried to set the .htacces file back to the wordpress default... and add this code to the functions.php file for my child theme:
function AJAX_rewrite_rule() {
add_rewrite_rule(
'^/(sub1|sub2)/(.*)$',
'http://www.example.com/$1',
'top' );
};
add_action( 'init', 'AJAX_rewrite_rule' );
Seems to slow the load of everything down, but all files not found are still redirected to the main page, not the subdirectory.
UPDATE #2
I think I was going the wrong direction, as add_rewrite_rule is only to add a rule to the structure already put in place by wordpress. This all works by interpreting URL's, and changing them to variables for a DB query run by index.
I'm pretty sure I need to use $wp_rewrite->non_wp_rules. If anyone has more of an idea, let me know.
Try this, you seem to have ine bad line there:
<IfModule mod_rewrite.c>
RewriteEngine On
# RewriteBase /
# RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f #Means DONT redirect if file exists.
RewriteCond %{REQUEST_FILENAME} !-d #Means DONT redirect if directory exists.
RewriteCond %{REQUEST_URI} !^/sub1/
RewriteCond %{REQUEST_URI} !^/sub2/
# RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]
RewriteRule . /index.php [L]
</IfModule>
What happens is, every time you add a "RewriteRule" all the "RewriteCond" are applied to that rule, and then you start with a blank slate:
RewriteCond A
RewriteCond B
RewriteCond C
RewriteRule Whatever [L] #This applies A, B, and C
RewriteRule Another [L] #This applies no rules
Perhaps that will help.
Also, you may try adding your "RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]" right after "RewriteEngine On" if that doesn't work…

Rewrite part of url .htacces

I need to redirect an url from
http://mydomain.com/download/filename.zip
to
https://dl.dropbox.com/u/0000/filename.zip
How can I do this using mod_rewrite?
Make a .htaccess file in root of your first domain, with this rule:
RewriteEngine On
RewriteRule download/(.+) https://dl.dropbox.com/u/0000/$1 [L,R=301]
# Check to see if mod_rewrite is installed / avaliable
<IfModule mod_rewrite.c>
RewriteEngine on
# Check to see if file or directory exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite to Dropbox URL. Make sure you change the data after "/u/" (9502594) to your own user ID
RewriteRule ^e/(.*)$ http://dl.dropbox.com/u/9502594/$1 [L,QSA] # Embedded File
RewriteRule ^(.*)$ http://dl.dropbox.com/u/9502594/$1?dl=1 [L,QSA] # Force Download (Default)
</IfModule>

Resources