Multiple rewrite cond in one htaccess file BUT - .htaccess

I am trying to get a URL shortener to work.
Instead of redirecting the link : http://urlshortner.com/33 to, say, yahoo.com, it just redirects it to http://urlshortner.com/yahoo.com.
But if I put the info from that .htaccess file that resides in my shortener subdir onto my MAIN .htaccess file (root level) the URL shortner redirect works correctly, but my MAIN page gives a 404 error.
Example:
I have many URLs on my server and my MAIN site on my server root.
So, my URL shortener is located at:
myserver/urlshortner which points to urlshortner dot com
and my main page is:
myserver/index.html which points to mymainpage dot com
I have an .htacess file at myserver/urlshortner/.htaccess that says:
RewriteEngine on
RewriteCond %{request_filename} -f
RewriteRule ^(.*) $1 [L]
RewriteRule ^(([^/]*)+)(/([^/]{0,32})(/.+)?)?$ index.php?a=$1&q=$3 [L]
And my .htacess file at my root directory that forces all requests to https etc:
# Begin IP blocking #
Order Allow,Deny
Deny from xxx.xx.xxx
Allow from all
# End IP blocking #
RewriteEngine On
RewriteCond %{HTTP_HOST} ^XXXXXX\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.XXXXXX.com/$1 [R,L]
AddType application/xspf+xml .xspf .xspf
BUT, when I combine them like this:
# Begin IP blocking #
Order Allow,Deny
Deny from xxx.xx.xxx
Allow from all
# End IP blocking #
RewriteEngine On
RewriteCond %{HTTP_HOST} ^XXXXXX\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.XXXXXX.com/$1 [R,L]
RewriteCond %{request_filename} -f
RewriteRule ^(.*) $1 [L]
RewriteRule ^(([^/]*)+)(/([^/]{0,32})(/.+)?)?$ index.php?a=$1&q=$3 [L]
AddType application/xspf+xml .xspf .xspf
The URL shortener works, but my main page gives a 404 error.
Any thoughts on this?

Related

htaccess serve page from another subdomain silently only when page is not found

My main pages are at "main.mysite.com".
Customer access site by "customer.mysite.com" which contains only a subset of the main pages.
When customer request page "customer.mysite.com/data.php", I want to check first if the file is in "customer.mysite.com" subdomain, if yes, then serve that page, if not, then serve the page at "main.mysite.com/data.php" subdomain.
I also want to keep the url at "customer.mysite.com/data.php" for the two cases.
My complete htaccess file is currently :
# This will enable the Rewrite capabilities
RewriteEngine On
RewriteBase /
# This rule will convert request urls like /category/page?id=1 to /?c=category&p=page&id=1
# Redirect to main page, which is Single Page Application and then manage to open the new tab
RewriteRule ^([A-Za-z]*)\/([A-Za-z]*)([?]?[A-Za-z0-9=&]*)$ /?c=$1&p=$2 [NC,R,QSA]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e. http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context
# First, this checks to make sure the connection is not already HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [NC]
# This rule will serve pages from main.mysite.com when browsed with customer.mysite.com
# By removing the [R=301], it makes an internal redirect, keeping the original url in the browser
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ https://main.mysite.com/$1 [L,NC,QSA]
# Disable Directory Listing
Options -Indexes
<Files .htaccess>
order allow,deny
deny from all
</Files>
However, when I browse "customer.mysite.com/page.php", I am redirected to "main.mysite.com/page.php", which is not what I want.
First , to redirect /category/page?id=1 to /?c=category&p=page&id=1 :
RewriteCond %{QUERY_STRING} ^id=(.*)$
RewriteRule ^([A-Za-z]+)\/([A-Za-z]+)$ /?c=$1&p=$2 [NC,R=301,QSA]
change this : RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [NC]
to this RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]
Because %{HTTP_HOST} it is request header including your target host
Moreover :
I f you handled error file like that , when there is no file in that target looping will happen so it is better to handle that like this :
replace this :
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ https://main.mysite.com/$1 [L,NC,QSA]
With this :
RewriteCond %{HTTP_HOST} !^(www\.)?main.mysite.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ https://main.mysite.com/$1 [L,NC,QSA]
#then you could handle the error that not found in main by this
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /path/to/error/page [L]
By adding the proxy flag [P] to the rule, the server makes an internal redirect, keeping the browser url unchanged. Normally, this would work by not specifying the R=301 flag, but it'S not enough when the rule is changing domain/subdomain.
What worked:
RewriteRule ^(.*)$ https://main.mysite.com/$1 [P,L,NC,QSA]
Note that the L flag is not required with P as it is added implicitely, as no other rules can be executed after that.

.htaccess specific url changes

I've a small, but hard to understand problem with .htaccess in CMS system.
I've mod expires, that cache stuff on whole website, but I don't want to cache stuff in /admin URL, I can't make another .htacess, couse I've MVC structure and no real directory that could hold all my admin stuff.
I've found directive, but it only works in server configuration and I want it to work on different hostings, so only in htaccess file.
EDIT- Rewrite
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteCond %{HTTP_HOST} ![0-9]$ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
# Protect hidden files from being viewed
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Protect application and system files from being viewed
RewriteRule ^(?:application|modules|system)\b.* index.php/$0 [L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
RewriteRule .* index.php/$0 [PT]
You can apply your Expires directive using a <if> directive with an expression to match against /admin:
<If "%{REQUEST_URI} =~ /^\/admin\//">
# Your expiry directives
</If>
If you know the exact URL then you can try this pattern.
RewriteRule ^facebook/get/(.*)?$ http://$1 [NC,R]
RewriteRule ^wrapper/share/(.*)?$ http://example.com/wrapper/share/$1 [NC,R]
This will check for URL where <-any-value->facebook/get/<-any-value2-> and then will send to the <-any-value2->
Like
RewriteRule ^stats/(.*)$ admin/dashboard.php?mode=openstats&event_id=$1 [NC,L,QSA]
**If URL has stats/<--any-value--> then it will redirect/open admin/dashboard.php **
If your URLs doesn't have exact value but you do know the URL slot pattern then you can try this.
RewriteRule ^([^/.]+)/([a-zA-Z0-9_-]+)/$ wrapper/index.php?id=$2 [NC,L,QSA]

Redirect to subfolder with same name on localhost

I have a webproject saved in a "base" folder of the domain "example.com" which contains a main.php and several subfolders. The second part of the code below redirects all requests (except main.php itself and page404.php) to this main.php and hands over the originally requested URL in the variable "path".
In addition there is a first part which redirects all requests of pages of the baseurl to a subfolder "folder1". So in the end the request of
www.example.com/somepage.php
will lead to
example.com/main.php?path=www.example.com/folder1/somepage.php
(Requests to other subfolders shall only be redirected to the main.php. So www.example.com/somefolder/somepage.php will lead to example.com/main.php?path=www.example.com/somefolder/somepage.php - without adding "folder1".)
The code below actually does what I want:
ErrorDocument 404 /page404.php
Options -Indexes
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine on
#first part: redirect to folder1/
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/*
RewriteCond %{REQUEST_URI} !^page404*
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ folder1/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ index.php
#second part: redirect to main.php
RewriteCond %{REQUEST_FILENAME} (.*)\.php [NC]
RewriteCond %{REQUEST_URI} !main\.php
RewriteCond %{REQUEST_URI} !page404\.php
RewriteRule ^([^?]*)$ /main.php?path=$1 [NC,L,QSA]
</IfModule>
But I have two questions:
Side question: I have the feeling that actually redirecting to "folder1" is way to complicated (even though it works) when I only want to add the "folder1" to the path variable in case a file of the base folder is called. Can you show me a better way to archieve this?
Main question: I have the same project on a localhost where the main folder is named "folder1" which contains the folder "folder1". So there the request of htttp://localhost/folder1/somepage.php shall lead to htttp://localhost/folder1/main.php?path=htttp://localhost/folder1/folder1/somepage.php (I replaced "http" by "htttp" to avoid automatic link recognition of SO) - How do I have to change the code above to have it working in the "localhost/folder1" scenario?
This stuff can be simplified:
ErrorDocument 404 /page404.php
Options -Indexes
DirectoryIndex index.php
RewriteEngine on
# ignore main.php, page404.php OR any files/directory for any rules below
RewriteCond %{REQUEST_URI} ^/(main|page404)\.php
RewriteRule ^ - [L]
#first part: /folder1/path
RewriteRule ^([^/]+?\.php)$ main.php?path=folder1/$1 [L,QSA]
#second part: rewrite to main.php
RewriteRule ^(.+?\.php)$ main.php?path=$1 [L,QSA]

.htaccess redirect & hide directory path in url

I have wordpress installed in root directory. I want to use some separate php files as a page on my domain, for which I have made a separate directory which holds all files for serving the php files, of which the directory structure is as:
the root folder has all the wordpress files
the directory which I'd like to serve as a page
/inc/css/
/inc/php/
/inc/img/
the CSS stylesheet files directory location in the PHP file is ../inc/css one step back & then css folder.
I want to hide folders from URL such as the files are served from the root (hide the /inc/php/, /inc/css/ & /inc/img/ folders from URL).
eg: www.domain.com/inc/php/about.php redirect & rewrite this URL to www.domain.com/about
the .htaccess in my root
RewriteEngine On
RewriteBase /
# disable directory browsing
Options -Indexes
# Prevent hotlinking of images htaccesstools.com/hotlink-protection
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?domain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|ico|pdf|flv|jpg|jpeg|mp3|mpg|mp4|mov|wav|wmv|png|gif|swf|css|js)$ - [NC,F,L]
RewriteRule ^login$ http://domain.com/wp-login.php [NC,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
<files wp-config.php>
order allow,deny
deny from all
</files>
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>
I have tried the simple redirect rule but the folders are exposed in the URL.
Redirect 301 /about.php /inc/php/about.php
also I have some more files in the PHP folder on which I'd like to apply the same rule of redirect & rewrite URL & hide folders from URL & remove the PHP extention.
www.domain.com/inc/php/about.php redirect & rewrite this URL to www.domain.com/about
This, of course, means that you can't have the same base filename that's a php file and, say, a css file. Since if the request is www.domain.com/about, is that supposed to map to /inc/php/about.php or /inc/css/about.css? Or is it an image? If you have both files, only one will get mapped to.
But if that's really what you want, try adding these rules right after the hotlinking rule that you have:
# Externally redirect requests for /inc/
RewriteCond %{THE_REQUEST} \ /inc/(php|img|css)/([^\?\ ]+)\.(php|css|jpe?g|png|gif) [NC]
RewriteRule ^ /%2 [L,R=301]
# Check if the request is a php file:
RewriteCond %{DOCUMENT_ROOT}/inc/php%{REQUEST_URI}.php -f
RewriteRule ^(.*)$ /inc/php/$1.php [L]
# Check if the request is a css file:
RewriteCond %{DOCUMENT_ROOT}/inc/css%{REQUEST_URI}.css -f
RewriteRule ^(.*)$ /inc/css/$1.css [L]
# Check if the request is a jpeg file:
RewriteCond %{DOCUMENT_ROOT}/inc/img%{REQUEST_URI}.jpg -f
RewriteRule ^(.*)$ /inc/img/$1.jpg [L]
# Check if the request is a gif file:
RewriteCond %{DOCUMENT_ROOT}/inc/img%{REQUEST_URI}.gif -f
RewriteRule ^(.*)$ /inc/img/$1.gif [L]
# Check if the request is a png file:
RewriteCond %{DOCUMENT_ROOT}/inc/img%{REQUEST_URI}.png -f
RewriteRule ^(.*)$ /inc/img/$1.png [L]

redirecting to multiple virtual subdomains using htaccess

I am trying to create subdomains via htaccess. The code below does exactly want I want
It takes http://domain.com and redirect it to http://www.domain.com
Options -Indexes
DirectoryIndex index.html index.htm index.asp index.php
ErrorDocument 401 http://www.domain.com
ErrorDocument 403 http://www.domain.com
ErrorDocument 404 http://www.domain.com
ErrorDocument 500 http://www.domain.com
ErrorDocument 507 http://www.domain.com
RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain.com$
RewriteRule ^(.*) http://www.domain.com/$1 [QSA,L,R=301]
AddType text/html .html .htm .asp
This is the part I am not to sure of:
RewriteCond %{HTTP_HOST} ^domain.com/nl$
RewriteRule ^(.*) http://nl.domain.com/$1 [QSA,L,R=301]
How can I create virtual subdomains so that if someone goes to http://nl.domain.com it would stay on http://nl.domain.com if someone types http://www.nl.domain.com it would take out the http://www.nl.domain.com and make it http://nl.domain.com also the directory structure for the subdomain would be http://www.domain.com/nl (This is where the actual files will be sitting).
so if someone goes to http://www.domain.com/nl it should also redirect to http://nl.domain.com.
Thanks in advance for any advice and pointers
RewriteEngine on
# The ordering of the following rules is somewhat important
#
# External redirects with HTTP "301 - Moved Permanently" for subdomains
#
# Redirect www.nl.example.com to nl.example.com
RewriteCond %{HTTP_HOST} ^www\.nl\.example\.com$
RewriteRule ^(.*) http://nl.example.com/$1 [QSA,L,R=301]
# Instead I could do this to redirect any prefix before nl to nl.example.com
# RewriteCond %{HTTP_HOST} ^.+?\.nl\.example\.com$
# RewriteRule ^(.*) http://nl.example.com/$1 [QSA,L,R=301]
# Redirect www.foo.example.com to foo.example.com
RewriteCond %{HTTP_HOST} ^www\.foo\.example\.com$
RewriteRule ^(.*) http://foo.example.com/$1 [QSA,L,R=301]
# Instead I could do this to redirect any prefix before foo to foo.example.com
# RewriteCond %{HTTP_HOST} ^.+?\.foo\.example\.com$
# RewriteRule ^(.*) http://foo.example.com/$1 [QSA,L,R=301]
# Rewrite any remaining subdomains to example.com
RewriteCond %{HTTP_HOST} !^example\.com$
RewriteCond %{HTTP_HOST} !^nl\.example\.com$
RewriteCond %{HTTP_HOST} !^foo\.example\.com$
RewriteRule ^(.*) http://example.com/$1 [QSA,L,R=301]
# Assuming from this point forward we have either
# example.com, nl.example.com, or foo.example.com as the HTTP_HOST
# Redirect example.com/nl to nl.example.com
# (Note that ONLY example.com/nl is caught here.)
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^nl(/(.*))? http://nl.example.com/$2 [QSA,L,R=301]
# Redirect example.com/foo to foo.example.com
# (Note that ONLY example.com/foo is caught here.)
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^foo(/(.*))? http://foo.example.com/$2 [QSA,L,R=301]
#
# Internal rewrites for directory structuring
#
# Internal rewrite for the nl subdomain
# - Match the subdomain exactly
RewriteCond %{HTTP_HOST} ^nl\.example\.com$
# - Check to see if the rewrite already happened (prevent
# infinite loop of internal rewrites)
RewriteCond %{REQUEST_URI} !^/nl(/.*|$)
# - Rewrite the URL to the subdirectory
RewriteRule ^(.*) /nl/$1 [L]
# Internal rewrite for the foo subdomain
# - Match the subdomain exactly
RewriteCond %{HTTP_HOST} ^foo\.example\.com$
# - Check to see if the rewrite already happened (prevent
# infinite loop of internal rewrites)
RewriteCond %{REQUEST_URI} !^/foo(/.*|$)
# - Rewrite the URL to the subdirectory
RewriteRule ^(.*) /foo/$1 [L]
I haven't tested the above on a server, but I tested it on my local server, it should be close to what you need if I understood you correctly.
I'm sure you've seen the mod_rewrite docs. In addition to that, the Rewrite Guide and the Advanced Rewrite Guide have helpful practical examples.

Resources