Load website in a subdirectory using .htaccess - .htaccess

I need to make a fully working backup of the actual site in a subdirectory, but I don't understand why it doesn't work, I mean the website is not showing correctly.
Here is the .htaccess code of the root directory. I need to make a backup in a subdirectory "/old/".
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^([a-z.]+)?example\.com$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .? http://www.%example.com%{REQUEST_URI} [R=301,L]
RewriteRule ^([^/]*)/css/(.*) /css/$2 [L]
RewriteRule ^([^/]*)/js/(.*) /js/$2 [L]
RewriteRule ^([^/]*)/fonts/(.*) /fonts/$2 [L]
RewriteRule ^([^/]*)/images/(.*) /images/$2 [L]
RewriteRule ^([^/]*)/templates/(.*) /templates/$2 [L]
RewriteRule ^([^/]*)/$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
Thank you for your help!

RewriteRule ^([^/]*)/css/(.*) /css/$2 [L]
RewriteRule ^([^/]*)/js/(.*) /js/$2 [L]
RewriteRule ^([^/]*)/fonts/(.*) /fonts/$2 [L]
RewriteRule ^([^/]*)/images/(.*) /images/$2 [L]
RewriteRule ^([^/]*)/templates/(.*) /templates/$2 [L]
RewriteRule ^([^/]*)/$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?lang=$1 [L]
You just need to remove the slash prefix from all the substitution strings in the above directives. You can then use the same .htaccess file in both the root and in the backup subdirectory.
For example:
RewriteRule ^([^/]*)/css/(.*) css/$2 [L]
RewriteRule ^([^/]*)/js/(.*) js/$2 [L]
RewriteRule ^([^/]*)/fonts/(.*) fonts/$2 [L]
RewriteRule ^([^/]*)/images/(.*) images/$2 [L]
RewriteRule ^([^/]*)/templates/(.*) templates/$2 [L]
RewriteRule ^([^/]*)/$ index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)$ index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ index.php?lang=$1 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)$ index.php?lang=$1 [L]
Removing the slash prefix makes the substitution relative to the directory that contains the .htaccess file.
These 9 directives can be reduced/simplified into 2 if you wish:
RewriteRule ^[^/]+/((?:css|js|fonts|images|templates)/.*) $1 [L]
RewriteRule ^([^/]+)(?:/[^/]*){1,3}$ index.php?lang=$1 [L]
UPDATE: I've fixed the regex in the 2nd "simplified" rule since when there is only one path segment the trailing slash is mandatory (previously it would not have matched if the trailing slash was included). For two and three path segments the trailing slash is effectively optional and for four path segments, there should be no trailing slash. Although whether that was really the intention of the original directives is another matter. The 2nd "simplified" rule now matches that behaviour. (Previously, it did not permit a trailing slash with any number of path segments.)
Aside:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^([a-z.]+)?example\.com$ [NC]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .? http://www.%example.com%{REQUEST_URI} [R=301,L]
You should reverse the order of these two rules. Otherwise, the first rule will prevent the canonical redirect (that prefixes the www subdomain) from happening on direct file requests.

Related

generic solution for Rewriteurl for all URL's [duplicate]

My website runs a script called -> WSS wallpaper script
My Problem -> I have been trying to force remove or add trailing slash to the end of my URL to prevent duplicated content and also to clean up my URLs.
I have tried all sorts and tried everything I could think of and loads from the interwebs but no such luck yet! It might be a quick fix but I have looked at it so much I am probably blind to something dead obvious.
So I present you with all my .htaccess code:
DirectoryIndex index.php
RewriteEngine on
RewriteRule ^download/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4&download=1 [L]
RewriteRule ^file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4 [L]
RewriteRule ^preview/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) wallpaper_preview.php?id=$1&width=$2&height=$3&name=$4 [L]
RewriteRule ^thumbnail/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/]+) image.php?wallpaper_id=$1&width=$2&height=$3&cropratio=$4&align=$5&valign=$6&file=$7 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&page=$3 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)-([0-9]+) index.php?task=category&id=$1&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+) index.php?task=category&id=$1&name=$2 [L]
RewriteRule ^tag/([^/\.]+)/([0-9a-zA-Z?-]+)/([0-9]+) index.php?task=tag&t=$1&sortby=$2&page=$3 [L]
RewriteRule ^tag/([^/\.]+) index.php?task=tag&t=$1 [L]
RewriteRule ^profile/([0-9]+)?/([^/\.]+) index.php?task=profile&id=$1&name=$2 [L]
RewriteRule ^profile/comments/([0-9]+)?/([^/\.]+) index.php?task=users_comments&id=$1&name=$2 [L]
RewriteRule ^page/([0-9]+) index.php?task=view_page&id=$1 [L]
RewriteRule ^register index.php?task=register [L]
RewriteRule ^lost-password index.php?task=lost_pass [L]
RewriteRule ^links index.php?task=links [L]
RewriteRule ^news/item/([0-9]+)/([^/\.]+) index.php?task=news&id=$1 [L]
RewriteRule ^news/page([0-9]+) index.php?task=news&page=$1 [L]
RewriteRule ^members/([^/\.]+)-([^/\.]+)/page([0-9]+)? index.php?task=member_list&sort=$1&order=$2&page=$3 [L]
RewriteRule ^members index.php?task=member_list [L]
RewriteRule ^messages index.php?task=messages [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^search/([^/\.]+) index.php?task=search&q=$1 [L]
RewriteRule ^search index.php?task=search [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^r-([0-9]+)?-([0-9]+)? go.php?id=$1&ref=$2 [L]
RewriteRule ^r-([0-9]+)? go.php?id=$1 [L]
RewriteRule ^([^/\.]+)/([0-9]+)/([^/\.]+) index.php?task=view&id=$2&name=$3 [L]
RewriteRule ^news/([^/\.]+) index.php?task=news&name=$1 [L]
RewriteRule ^profile/([^/\.]+) index.php?task=profile&name=$1 [L]
RewriteRule ^news index.php?task=news [L]
RewriteRule ^page/([^/\.]+) index.php?task=view_page&name=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([0-9a-zA-Z'?-]+)/([0-9]+) index.php?task=category&name=$1&sortby=$2&page=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([^/\.]+) index.php?task=view&name=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+) index.php?task=category&name=$1 [L]
## www reslove ##
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
## www reslove ##
## index reslove ##
Options +FollowSymLinks
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ http://www.epicwallpaper.net/$1 [R=301,L]
## index reslove ##
Right below the RewriteEngine On line, add:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R] # <- for test, for prod use [L,R=301]
to enforce a no-trailing-slash policy.
To enforce a trailing-slash policy:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R] # <- for test, for prod use [L,R=301]
EDIT: commented the R=301 parts because, as explained in a comment:
Be careful with that R=301! Having it there makes many browsers cache the .htaccess-file indefinitely: It somehow becomes irreversible if you can't clear the browser-cache on all machines that opened it. When testing, better go with simple R or R=302
After you've completed your tests, you can use R=301.
To complement Jon Lin's answer, here is a no-trailing-slash technique that also works if the website is located in a directory (like example.org/blog/):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]
For the sake of completeness, here is an alternative emphasizing that REQUEST_URI starts with a slash (at least in .htaccess files):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L] <-- added slash here too, don't forget it
Just don't use %{REQUEST_URI} (.*)/$. Because in the root directory REQUEST_URI equals /, the leading slash, and it would be misinterpreted as a trailing slash.
If you are interested in more reading:
PR 3145 for Laravel
A discussion on commit 343c31e
(update: this technique is now implemented in Laravel 5.5)
This is what I've used for my latest app.
# redirect the main page to landing
##RedirectMatch 302 ^/$ /landing
# remove php ext from url
# https://stackoverflow.com/questions/4026021/remove-php-extension-with-htaccess
RewriteEngine on
# File exists but has a trailing slash
# https://stackoverflow.com/questions/21417263/htaccess-add-remove-trailing-slash-from-url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)/+$ /$1 [R=302,L,QSA]
# ok. It will still find the file but relative assets won't load
# e.g. page: /landing/ -> assets/js/main.js/main
# that's we have the rules above.
RewriteCond %{REQUEST_FILENAME} !\.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^/?(.*?)/?$ $1.php
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
## hide .html extension
# To externally redirect /dir/foo.html to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+).html
RewriteRule ^ %1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)/\s
RewriteRule ^ %1 [R=301,L]
## To internally redirect /dir/foo to /dir/foo.html
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^\.]+)$ $1.html [L]
<Files ~"^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</Files>
This removes html code or php if you supplement it. Allows you to add trailing slash and it come up as well as the url without the trailing slash all bypassing the 404 code. Plus a little added security.

Rewrite gives a 404 error

I need to rewrite an url from this
https://www.domain.tld/stand-carros-usados/?brand=2&model=&category=&fuel=&kms=&price=
to this
https://www.domain.tld/stand-carros-usados/alfa-romeo
and the code is this
RewriteCond %{REQUEST_URI} ^/stand-carros-usados [NC]
RewriteCond %{QUERY_STRING} ^brand=(.*)&model=(.*)&category=(.*)&fuel=(.*)&kms=(.*)&price=(.*)
RewriteRule ^(.*)$ https://www.domain.tld/stand-carros-usados/alfa-romeo? [L]
The url is changing the one i want but its gives me a 404 page?
Anyone knows why?
EDIT
This is the .htaccess file i have. A bit messi because who created didnĀ“t care that much.
RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteRule ^pt/(.*)$ http://%{HTTP_HOST}/$1 [L,R]RewriteCond %
{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^viaturas(.*)$ https://%{HTTP_HOST}/stand-carros-usados$1 [R=301,L]
RewriteRule ^automoveis(.*)$ https://%{HTTP_HOST}/stand-carros-usados$1 [R=301,L]
RewriteRule ^print/([a-zA-Z0-9_-]+)?$ ajax/printcar.php?id=$1 [L]
RewriteRule ^process-order/([a-zA-Z0-9_-]+)?$ process-order.php?h=$1 [L]
RewriteRule ^([^\.]+)?$ index.php?section=$1 [L]
RewriteRule ^eng/([^\.]+)?$ index.php?section=$2 [L]
RewriteRule ^eng?$ index.php [L]

Do I always need RewriteCond?

I have this snippet in my .htaccess file:
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^(20\d\d)/page/([0-9]+)/$ ?yearMeasure=$1&page=$2 [L]
RewriteRule ^(20\d\d)/$ ?yearMeasure=$1 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/page/([0-9]+)/$ ?category=$1&page=$2 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/$ ?category=$1 [L]
RewriteRule ^(20\d\d)/([A-Za-z0-9-]+)/$ ?type=post&year=$1&title=$2 [L,QSA]
However, when I remove the first line, the website still behaves in the same way. The URLs still remain "clean." This brings me to my question; what is the significance of RewriteCond in this snippet?
The only RewriteRule this RewriteCond affected was this:
RewriteRule ^page/([0-9]+)/$ ?page=$1 [L]
...when I attempted to visit /page/2/, it didn't work.
When I moved it above the RewriteCond as follows:
RewriteRule ^page/([0-9]+)/$ ?page=$1 [L]
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^(20\d\d)/page/([0-9]+)/$ ?yearMeasure=$1&page=$2 [L]
RewriteRule ^(20\d\d)/$ ?yearMeasure=$1 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/page/([0-9]+)/$ ?category=$1&page=$2 [L]
RewriteRule ^category/([A-Za-z0-9-]+)/$ ?category=$1 [L]
RewriteRule ^(20\d\d)/([A-Za-z0-9-]+)/$ ?type=post&year=$1&title=$2 [L,QSA]
...everything came back to normal. Why?
In the docs RewriteRule is defined this way:
RewriteRule Pattern Substitution [flags]
If Pattern matches the url requested (domain.com/path/file.cgi), the url is replaced with the Substitution (either a redirect header is returned or the url is changed internally depending on the flags)
This rewrite rule:
RewriteRule ^(20\d\d)/page/([0-9]+)/$ ?yearMeasure=$1&page=$2 [L]
will check if the url matches the pattern and the replacement will occur only in this case. That's why here such RewriteCond is useless:
RewriteCond %{QUERY_STRING} id=([0-9]+)
It's useful in situations that RewriteRule can't capture like checking the hostname or whether a file exists:
RewriteCond %{HTTP_HOST} !^example.com$ [NC]
RewriteRule .? http://example.com%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
http://www.sitepoint.com/apache-mod_rewrite-examples-2/

Htacces mod_rewrite sub directory

I'm having a problem with my .htaccess mod_rewrite. I've made a simple custom CMS and i've put this in a sub directory of my domain; http://www.example.com/cms
I've got the following situations:
cms/index.php?page=modules/pages/index.php
convert to
cms/modules/pages/index
and
cms/index.php?page=modules/pages/edit.php?id=1
convert to
cms/modules/pages/edit/1
I've got it working with a subdomain, but when i use example.com/cms it doesn't do anything
i've made this .htaccess but i couldn't get it working...
RewriteEngine On
Options +FollowSymlinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule ^(.*?)$ $1 [L]
RewriteRule ^/cms/([^/]*)/$ cms/index.php?page=$1 [L,QSA]
RewriteRule ^/cms/([^/]*)$ /cms/index.php?page=$1 [L,QSA]
RewriteRule ^/cms/pages/([^/]*)/$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/cms/pages/([^/]*)$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/cms/modules/([^/]*)/([^/]*)/$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/cms/modules/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/cms/modules/([^/]*)/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2&id=$3 [L,QSA]
If this is in an htaccess file, the URI's have their prefix removed (the leading slash), so those patterns won't match anything. Either remove the leading slash from the pattern or make it optional (with a ?):
RewriteRule ^/?cms/([^/]*)/$ cms/index.php?page=$1 [L,QSA]
RewriteRule ^/?cms/([^/]*)$ /cms/index.php?page=$1 [L,QSA]
RewriteRule ^/?cms/pages/([^/]*)/$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/?cms/pages/([^/]*)$ /cms/index.php?page=pages/$1 [L,QSA]
RewriteRule ^/?cms/modules/([^/]*)/([^/]*)/$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/?cms/modules/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2 [L,QSA]
RewriteRule ^/?cms/modules/([^/]*)/([^/]*)/([^/]*)$ /cms/index.php?page=modules/$1/$2&id=$3 [L,QSA]
Additionally, your first rule can be simplified to just:
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule ^ - [L]

.htaccess, cannot get first part of a URL in rewrite condition

I am attempting to get the following results with an .htaccess file.
URL: Behavior(rewrite to):
example.com/x/ view-test.php?page=x
example.com/x/y view-test.php?page=y&parent=x
example.com/x/y/z view-test.php?page=z&parent=y&grandparent=z
I have the following .htaccess rules, which also include some folders which needs to ignore this scheme:
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]*)/([^/]*)/([^/]+)/?$ /view-test.php?grandparent=$1&parent=$2&page=$3 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]*)/([^/]+)/?$ /view-test.php?&parent=$1&page=$2 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
#RewriteRule ([^/]+)$ /view-test.php?page=$1 [L]
however, whenever I uncomment the last two lines I get an internal server error. the parent/page and grandparent/parent/page structures work fine. How can I re-write this last rule (and the preceding rules if nessecary) to achieve the desired result for the first pattern (just a page)?
# remove slash at the end to prevent redirect loop
RewriteCond %{REQUEST_URI} ^/(OIE|admin|images|scripts|css|fonts|view-test\.php) [NC]
RewriteRule ^ - [L]
RewriteRule ([^/]*)/([^/]*)/([^/]+)/?$ /OIE/view-test.php?grandparent=$1&parent=$2&page=$3 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]*)/([^/]+)/?$ /OIE/view-test.php?&parent=$1&page=$2 [L]
RewriteCond %{REQUEST_URI}!^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ([^/]+)/?$ /OIE/view-test.php?page=$1 [L]
Use this code instead:
RewriteCond %{REQUEST_URI} ^/(admin|images|scripts|css|fonts|view-test\.php)/ [NC]
RewriteRule ^ - [L,S=3]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ view-test.php?grandparent=$1&parent=$2&page=$3 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ view-test.php?&parent=$1&page=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ view-test.php?page=$1 [L,QSA]
Problem was that you were missing trailing slash / in in your last RewriteRule condition.
Try this :
RewriteEngine On
RewriteBase /
RewriteRule ^([a-zA-Z0-9_-]+)$ view-test.php?page=$1
RewriteEngine On
RewriteBase /
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ view-test.php?page=$1&parent=$2
RewriteEngine On
RewriteBase /
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ view-test.php?page=$1&parent=$2&grandparent=$3

Resources