Apache cannot detect and rewrite URLs to lowercase - mod-rewrite

What am I trying to achieve?
I want to convert all URL's that are within the /migrate directory (and subdirectories) to lowercase.
What have I done?
I have migrated my website from DNN to Wordpress. Therefore I have URL's in my posts that reference images with a combination of upper and lowercase letters.
All of my directories and files on disk in the /migrate folder (and subfolders) are lowercase.
When I view an article, if the reference to the image has an uppercase character, I am getting a 404 which is expected.
For example:
https://xxx.domain.net/wp-content/migrate/ABC/image.jpg
https://xxx.domain.net/wp-content/migrate/Xyz/image.jpg
https://xxx.domain.net/wp-content/migrate/abc/Image.jpg
https://xxx.domain.net/wp-content/migrate/ABC/Xyz/image.jpg
So after reading various articles online and on here I tried a few things:
1) Enabled mod_speling and added this to apache2.conf
LoadModule speling_module /usr/lib/apache2/modules/mod_speling.so
<IfModule mod_speling.c>
CheckSpelling On
CheckCaseOnly On
</IfModule>
This didn't work, continued to get 404's.
2) Tired to use Rewritemap in my /etc/sites-enabled/mysite.conf file.
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} /migrate [A-Z]
RewriteRule ^(.*)$ /${lc:$1} [R=301,L]
However this would rewrite all URL's to lowercase and it broke some of the Wordpress plugins and editors as the files on disk had uppercase characters.
My .htaccess file in the Wordpress root directory is as follows:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
#BEGIN Wordpress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

After hours and hours of trying different things and reading through the logs, I have worked this out!
Basically I needed to ignore all the other Wordpress directories from rewriting.
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} [A-Z]
RewriteCond %{REQUEST_URI} !^/wp-content/uploads/
RewriteCond %{REQUEST_URI} !^/wp-content/themes/
RewriteCond %{REQUEST_URI} !^/wp-content/plugins/
RewriteCond %{REQUEST_URI} !^/wp-includes/
RewriteCond %{REQUEST_URI} !^/wp-admin/
RewriteRule ^/?(.*)$ /${lc:$1} [R=301,L]

Related

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

How to redirect a child URL to parent post URL? [duplicate]

in .htaccess I would like to chop off anything after the 2nd '/'… so http://www.domain.com/parent/child/otherchild would be redirected to http://www.domain.com/parent/
Add these rules to the htaccess file in your document root:
RewriteEngine On
RewriteRule ^([^/]+)/.+$ /$1/ [L,R=301]
Not sure what you meant by pasting all that unreadable code in the comments, but you want to add exclusion conditions like I mentioned in my comments:
AddType application/octet-stream vcf
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.(css|js)$ [NC]
RewriteRule ^([^/]+)/.+$ /$1/ [L,R=301]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} !^/wp-content/themes/myTheme/style.css
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
This line is an exclusion, because of the !:
RewriteCond %{REQUEST_URI} !\.(css|js)$ [NC]
That means if the URI ends with .css or .js then don't apply the rule. You can add others as needed. Say you don't want to redirect a URI like: /foo/bar/no-redirect/, then also add:
RewriteCond %{REQUEST_URI} !^/foo/bar/no-redirect/
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteRule ^([^/]+/).+$ /$1 [L,R=301]

How to exclude certain sections of a site from Mod ReWrite Rules

I am moving most pages from a site and I want to redirect all requests to a 404 error page except all/any pages in a certain cname on the site, all/any pages in a certain sub-directory on the site and a certain page in a certain directory on the site.
Here is what I have so far:
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_HOST} !^blogs.example.com [NC]
RewriteCond %{REQUEST_URI} !^/private [NC]
RewriteCond %{REQUEST_URI} !^/public/special-form.php [NC]
RewriteCond %{REQUEST_URI} !^/public/special-form_submitted.php [NC]
RewriteCond %{REQUEST_URI} !^/error404.php [NC]
RewriteRule ^(.*) http://example.com/error404.php [R=301,L]
Your issue is mainly the / at the start of your RewriteRule, why?
Because you're using it with an .htaccess so the RewriteRule path starts without the / at the begin.
If it was inside the VirtualHost then that would have worked just fine.
Basically this is what your rule is telling the server to do after our comments conversation and your update:
Options +FollowSymlinks
RewriteEngine On
# if domain is not blogs.example.com
RewriteCond %{HTTP_HOST} !^blogs.example.com [NC]
# and if address does not start with /private
RewriteCond %{REQUEST_URI} !^/private [NC]
# and if the file is not /public/special-form.php
RewriteCond %{REQUEST_URI} !^/public/special-form.php [NC]
# and if the file is not /public/special-form_submitted.php
RewriteCond %{REQUEST_URI} !^/public/special-form_submitted.php [NC]
# and if the file is not /error404.php
RewriteCond %{REQUEST_URI} !^/error404.php [NC]
# then redirect to http://example.com/error404.php
RewriteRule ^ http://example.com/error404.php [R=301,L]
So anything else including images or css or not listed on the conditions would be redirected, in order to avoid that you would have to verify all the needed files within those 2 php pages and white list it, for example with a condition like this:
RewriteCond %{REQUEST_URI} !^/public/[^.]+\.(css|pdf|jpg|doc)$ [NC]
Basically the above means anything within the public folder that ends with .css or .pdf or .doc or .jpg should be displayed.
NOTE: Keep in mind that if your images and documents and whatever else you need to show to your users from those 2 PHP pages are not within the public folder the above will not work, that was merely an example to illustrate an easy way to couple multiple types of files into it.
You could also resume this 2 conditions:
RewriteCond %{REQUEST_URI} !^/public/special-form.php [NC]
RewriteCond %{REQUEST_URI} !^/public/special-form_submitted.php [NC]
as follow:
RewriteCond %{REQUEST_URI} !^/public/(special-form_submitted|special-form)\.php [NC]
You would end with:
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_HOST} !^blogs.example.com [NC]
RewriteCond %{REQUEST_URI} !^/private [NC]
RewriteCond %{REQUEST_URI} !^/public/(special-form_submitted|special-form)\.php [NC]
RewriteCond %{REQUEST_URI} !^/public/[^.]+\.(css|pdf|jpg|doc)$ [NC]
RewriteCond %{REQUEST_URI} !^/error404.php [NC]
RewriteRule ^ http://example.com/error404.php [R=301,L]
Just a side information, since you're redirecting anything that does not match the conditions and you're not passing along anything to the redirect, you don't need the (.*), merely using ^ alone will do the job.

Protecting image/video folder in cakephp 2.0

We're currently using folders inside webroot to store images and videos which we're loading in views (using the usual html image helper) that require log in.
How can I prevent outside visitors from just doing a site.com/img/photos/1.jpg url and having access to the images?
From what I understand I can't really use media views to render an image inside a proper view, and I can't figure out if there's a solution through htaccess manipulation.
Which is the best practise for this?
Perhaps choosing to go with a non-webroot folder would be best (although that would make it harder in the file-storing part)?
As poncha suggested, I tried editing the main .htaccess file into this
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER} !localhost
RewriteCond %{REQUEST_URI} ^app/webroot/img/
RewriteRule .* / [L,F]
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
But the rewrite base line seems to be forbidding access to the whole site, and without it there seems to be no change in img access.
Edit 2:
Editing the htaccess inside webroot:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
# this RewriteCond is needed to avoid rewrite loops
RewriteCond %{REQUEST_URI} !^/app/webroot/
RewriteRule (.*) app/webroot/$1 [L,R]
RewriteCond %{HTTP_REFERER} !127.0.0.1
RewriteCond %{REQUEST_URI} ^/app/webroot/img/
RewriteRule .* - [L,F]
</IfModule>
This checks if Referer http header is set to something containing your domain, and denies access to img/ folder if not.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} !site.com
RewriteCond %{REQUEST_URI} ^img/
RewriteRule .* / [L,F]
Note: it is easy enough to "break" this protection if someone wants to steal your content, however, it does prevent hotlinking without the need to produce some sort of script that would pass thorugh all the images/videos to check if access should be granted.
EDIT:
In case your website is not in /, You have two options:
Change RewriteBase to reflect the base uri of the site (eg RewriteBase /app/webroot/)
Change RewriteCond to reflect the path from / (eg RewriteCond ^app/webroot/img/)
The second option is preferred in your case because you have other rules there
EDIT2:
In your case, the whole set should look like this:
RewriteEngine on
RewriteBase /
# this RewriteCond is needed to avoid rewrite loops
RewriteCond %{REQUEST_URI} !^/app/webroot/
RewriteRule (.*) app/webroot/$1 [L,R]
RewriteCond %{HTTP_REFERER} !localhost
RewriteCond %{REQUEST_URI} ^/app/webroot/img/
RewriteRule .* - [L,F]

Skipping a entire directory using Helicon ISAPI rewrite v3.0

Here is my current .htaccess file. This file is in my root directory for my site.
I want to add a rule that in plain english will do the following.
COMPLETELY SHUT OFF RULES PROCESSING FOR
http://www.sc-pa.com/dr405/*.*
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} (www.sarasotaproperty.net|www.sc-pa.net|sc-pa.net|sarasotaproperty.net) [nc]
#RewriteRule ^(.*)$ http://www.sc-pa.com/$1 [R=301,NC,QSA]
RewriteRule (.*)/eurl\.axd/[0-9a-f]+ /$1 [L]
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} [A-Z]
RewriteCond %{REQUEST_URI} !.*(js|css|inc|jpg|gif|png)
RewriteRule (.*) ${lc:$1} [R=301]
RewriteCond %{REQUEST_URI} !.*(web_content/pdf/|/dr405/).*
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule (?!.*/web_content/pdf/)([^/]*?\.pdf) /web_content/pdf/$1 [R=301]
RewriteRule pasite-(.*\.asp)$ /content/$1 [R=301,QSA]
RewriteRule home\.asp$ / [R=301]
#RewriteRule ^search/tpp/?$ content/search_tangible.asp
#RewriteRule ^search/?$ content/search_real_property.asp
#RewriteRule ^downloads/?$ content/downloads.asp
#RewriteRule ^(.*?view)/([^/]*)/([^/]*)(/.+)? /search/parcel_detail.asp?account=0&$2=$3 [NC,LP,QSA,R=301]
If you need to completely disable rewriting and .htaccess files for this directory and subdirectories you may use section in the HTTPD.CONF file. Here is an example:
<Directory C:/inetpub/mysite/dr405>
RewriteEngine off
AllowOverride None
</Directory>
Please note you need to use fully qualified path, i.e. C:/intepub...
If you simply want to exclude this directory so rules from current .htaccess file will not be applied you may place this rule at the beginning of your site's .htaccess file:
RewriteBase /
RewriteRule ^dr405 - [L]
RewriteCond %{HTTP_HOST} (www.sarasotaproperty.net|www.sc-pa.net|sc-pa.net|sarasotaproperty.net) [nc]
#RewriteRule ^(.*)$ http://www.sc-pa.com/$1 [R=301,NC,QSA]
RewriteRule (.*)/eurl\.axd/[0-9a-f]+ /$1 [L]
# ... etc....
Moved the site to IIS7 and used the built in rewrite module.

Resources